Next.js: The React Framework (App Router)Entry 10 of 16

Caching and Revalidation

With cacheComponents enabled, 'use cache' caches the result of a function or component. cacheLife sets how long; cacheTag labels it so it can be refreshed on demand.

Notes

  • Enable in next.config.ts: cacheComponents: true. Without it, Next.js 16 renders dynamically by default and caches nothing implicitly.
  • cacheLife(profile): built-in profiles such as 'seconds', 'minutes', 'hours', 'days', 'max'.
  • cacheTag('posts'): names the cache entry.
  • Refreshing:
    • updateTag('posts') in a Server Action: expires the tag so the user sees their own change immediately.
    • revalidateTag('posts', 'max'): marks it stale and refreshes in the background (stale-while-revalidate), e.g. from a CMS webhook.
    • revalidatePath('/posts'): refreshes everything for a path.
  • Cached functions can't read cookies() or headers() directly; pass the values in as arguments, or use 'use cache: private'.

What / Why / When

What

Server-side caching of data and rendered output with on-demand invalidation.

Why

Fast responses without hitting the database on every request, and fresh data right after a change.

When

Data shared by many users that changes occasionally.

Use case

A posts list cached for an hour, refreshed when a post is created.

Code compare

Next.js
// next.config.tsimport type { NextConfig } from "next";​const nextConfig: NextConfig = {  cacheComponents: true,};​export default nextConfig;
Next.js
// lib/posts.tsimport "server-only";import { cacheLife, cacheTag } from "next/cache";​export async function getPosts() {  "use cache";  cacheLife("hours");  cacheTag("posts");​  const res = await fetch(`${process.env.API_URL}/posts`);  return (await res.json()) as Post[];}
Next.js
// app/api/revalidate/route.ts — called by a CMS webhookimport { revalidateTag } from "next/cache";​export async function POST() {  revalidateTag("posts", "max");  return Response.json({ revalidated: true });}

Angular has no built-in server data cache. The options are:

  • Prerendering (RenderMode.Prerender): pages are cached as static files until the next build.
  • HTTP transfer cache: avoids fetching the same data twice on first load (server → browser), not across users.
  • Backend or CDN caching: Cache-Control headers from your Go API or server.ts.
Angular
// server.ts — cache-control on server-rendered responsesapp.use((req, res, next) => {  if (req.path.startsWith("/posts")) {    res.setHeader("Cache-Control", "public, s-maxage=3600, stale-while-revalidate=86400");  }  next();});
Angular
// app.config.ts — tune the transfer cacheprovideClientHydration(withHttpTransferCacheOptions({ includeHeaders: ["ETag"] }));

Differences and gotchas

  • This is the biggest gap between the two: Next.js treats caching as a framework feature; in Angular it's the backend's or CDN's job.
  • updateTag only works in Server Actions. Use revalidateTag from route handlers and webhooks.
  • Next.js 16 requires the second argument to revalidateTag; the one-argument form is deprecated.

Quick reference

Next.jsAngular
'use cache'No built-in equivalent
cacheLife('hours')Cache-Control: s-maxage=3600 (CDN/backend)
cacheTag + revalidateTagBackend/CDN purge
Prerendered static pageRenderMode.Prerender