Skip to main content

Store and expire data in Runtime Cache

Use getCache() for a regional key/value cache shared by your functions, with global tag expiry and plan quotas.

Runtime Cache is a regional key/value store shared by your functions. Use it for computed fragments, database results, and other short-lived data that doesn't belong in your primary database. It implements the same getCache() contract as @vercel/functions, backs Next.js 'use cache: remote', and Easel connects every deployment to it automatically, with no credentials or setup.

For complete HTTP responses at the edge, use CDN caching instead.

How it works

  • Regional. Each region has its own cache. A function reads and writes the cache in its home region, the edge region that invoked it.
  • Persists across deployments. On Pro, each project has one cache per environment (production and preview). On Hobby, each workspace has one cache per environment, shared by its projects. Changing plan starts a fresh, empty cache.
  • Best-effort. When a cache is full, Easel evicts the least recently used entries. Entries survive routine edge restarts and deploys, but no entry is guaranteed to last its full TTL.
  • Never stale. After a delete, an overwrite, or a tag expiry, the old value is never served. A miss is always possible, so your code must handle one.

Using Runtime Cache

Pick your stack. Both paths use the same cache and the same tags.

app/products/[id]/page.tsx
import { cacheLife, cacheTag } from "next/cache";

async function getProduct(id: string) {
  "use cache: remote";
  cacheTag(`product-${id}`, "products");
  cacheLife({ expire: 3600 });
  return loadProduct(id);
}

export default async function Page({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  const product = await getProduct(id);
  return <pre>{JSON.stringify(product, null, 2)}</pre>;
}

You can also call getCache() from Next.js Route Handlers, as in the Other example.

Expire by tag

app/actions.ts
"use server";

import { revalidateTag } from "next/cache";

export async function updateProduct(id: string) {
  await saveProduct(id);
  revalidateTag(`product-${id}`);
  revalidateTag("products");
}

Tag expiry is global: it reaches every region, typically well under a second. Tags are one namespace across Easel's caches, so revalidateTag and revalidatePath also expire getCache() entries with that tag, and getCache().expireTag also purges ISR, CDN, and 'use cache' entries with that tag. See Invalidate and revalidate cached content.

Next.js 'use cache'

Plain 'use cache' uses Next.js's built-in in-memory cache in each function instance, checked against Easel's global tag state so an expired tag is never served. Use 'use cache: remote' when you want entries shared across instances in a region through Runtime Cache.

API surface

  • get: returns the stored value, or a miss when missing or expired
  • set: writes a value; optional ttl (seconds), tags, and name
  • delete: removes one key
  • expireTag: removes every entry that carried that tag (or tags)

Storage

Each cache has a storage limit per region; see Runtime Cache limits. Writes over the limit don't fail: Easel evicts the least recently used entries in that cache and region to make room. On Hobby, all projects in a workspace share one cache, so namespace keys per feature so one workload doesn't crowd out another.

The project's Purge cache action purges the Runtime Cache that the live deployment uses; on Hobby, that's the workspace's shared cache. Deleting a project or workspace purges its caches. Cache observability shows reads, writes, hit rate, revalidations, and storage used per region.

Only hits and stored writes are billed; see Pricing.

Next steps