Cache Components

Cache Explorer

In Next 16, work is dynamic unless you cache it. Add "use cache" on a file, a component, or an async function. Two examples below, then the invalidate buttons.

01

Component-level "use cache"

docs ↗

Put "use cache" on a Server Component to cache the whole subtree, fetches included. Tags tie it to the buttons below.

export async function MyComponent() {
  "use cache";
  cacheTag("cache-explorer-component");
  cacheLife("minutes");

  const data = await fetchSomething();
  return <div>{data.renderedAt}</div>;
}

Invalidate this cache entry:

02

Function-level "use cache" with cacheLife()

docs ↗

Same directive on an async function. cacheLife() sets the TTL (e.g. minutes or hours) instead of the old revalidate export.

export async function getCachedData() {
  "use cache";
  cacheTag("cache-explorer-function");
  cacheLife("hours"); // longer TTL

  return { value: Math.random(), cachedAt: new Date() };
}

Invalidate this cache entry:

03

revalidateTag() vs updateTag()

docs ↗

The two invalidation APIs have different semantics. revalidateTag purges immediately and blocks the next request; updateTag marks the entry stale and lets the next request trigger a background refresh.

revalidateTag(tag, profile)
  • • Immediately purges the cache entry
  • • Next request blocks while fresh data is fetched
  • • Use when you need guaranteed fresh data now
  • • E.g. after a form submission or data mutation
updateTag(tag)
  • • Marks the entry as stale without purging it
  • • Next request is served stale data; revalidates in background
  • • Use for non-critical content where speed matters
  • • Only works inside a Server Action (read-your-own-writes)