Cache Components
With cacheComponents: true caching is explicit: nothing is cached unless you ask for it with the 'use cache' directive.
import { cacheLife, cacheTag } from 'next/cache';
export async function getProducts() {
'use cache';
cacheLife('hours');
cacheTag('products');
return db.query('SELECT * FROM products');
}'use cache' can be placed in a data function, in a component or at the top of a file. Arguments and captured variables become the cache key, so different inputs get separate entries.
Three kinds of content on a page
| Content | How | Where it ends up |
|---|---|---|
| Static (no I/O) | Nothing to do | Prerendered static shell |
| Cached data | 'use cache' + cacheLife | Static shell, revalidated in the background |
Request data (cookies(), uncached fetch) | Wrap in <Suspense> | Streams in at request time |
cacheLife profiles
cacheLife sets stale (client), revalidate (background refresh) and expire (hard limit). Profiles: seconds, minutes, hours, days, weeks, max or a custom object. Very short lifetimes are excluded from the prerender and become dynamic.
Variants
'use cache: private'- may readcookies()/headers(), cached per user.'use cache: remote'- durable shared cache handler instead of in-memory (useful on serverless).
How it differs from earlier versions
- Next.js 14:
fetchwas cached by default, which surprised many people. - Next.js 15:
fetchand GET Route Handlers stopped being cached by default. - Next.js 16:
'use cache'makes caching opt-in and works for any async code, not onlyfetch.
Values like
Date.now()orMath.random()must be either cached or read afterawait connection()inside<Suspense>, otherwise the dev overlay reports a blocking prerender.
updated