Caching

Next.js 16 introduces a refined caching model centred around the "use cache" directive and improved revalidation APIs. Understanding these patterns is key to building fast documentation sites.

Cache Components

The "use cache" directive can be applied at the file, component, or function level. The compiler automatically generates cache keys.

app/docs/page.tsx
"use cache"

export default async function DocsPage() {
  const docs = await fetchDocs()
  return <article>{/* Cached output */}</article>
}

Enable Cache Components in your config:

next.config.mjs
const nextConfig = {
  cacheComponents: true,
}

export default nextConfig

Revalidation

Use revalidateTag() with a cache life profile to control how long cached data remains fresh:

app/actions.ts
"use server"

import { revalidateTag } from "next/cache"

export async function updateDocs() {
  // Revalidate with a built-in profile
  revalidateTag("docs-content", "max")

  // Or use a custom revalidation time (seconds)
  revalidateTag("docs-content", { revalidate: 3600 })
}

New in Next.js 16

revalidateTag() now requires a cache life profile as the second argument. Built-in profiles include "max", "days", and "hours".

On-demand revalidation

Two new APIs provide finer control over cache invalidation:

  • updateTag() — Provides read-your-writes semantics in Server Actions
  • refresh() — Refreshes uncached data only, without touching the cache
Server Action example
"use server"

import { updateTag, refresh } from "next/cache"

export async function publishDoc(docId: string) {
  await saveToDatabase(docId)

  // Read-your-writes: immediately see the update
  updateTag(`doc-${docId}`)

  // Refresh only uncached data
  refresh()
}

Best practices

  • Use "use cache" for all documentation pages that source content from files or a CMS
  • Apply cache at the most granular level — individual components or functions rather than entire pages where possible
  • Use revalidateTag() with the "max" profile for documentation content that changes infrequently
  • Prefer updateTag() in admin workflows where editors need to see changes immediately