Next.js 16 (October 2025) changes the caching model. Earlier App Router versions cached aggressively by default, which surprised many teams. With Cache Components, code is dynamic at request time unless you opt in with the "use cache" directive. It builds on Partial Pre-Rendering: a static shell is served instantly and dynamic parts stream in.
Enable it
// next.config.ts
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
cacheComponents: true,
};
export default nextConfig;
Cache a function
import { cacheLife, cacheTag } from 'next/cache';
export async function getProducts() {
'use cache';
cacheLife('hours');
cacheTag('products');
const res = await fetch('https://api.example.com/products');
return res.json();
}
cacheLife sets how long the entry lives and cacheTag lets you invalidate it later.
Cache a component, stream the rest
import { Suspense } from 'react';
async function Reviews({ id }: { id: string }) {
const reviews = await fetchReviews(id); // per-request data
return <ReviewList items={reviews} />;
}
async function ProductInfo({ id }: { id: string }) {
'use cache';
const product = await fetchProduct(id);
return <h1>{product.name}</h1>;
}
export default async function Page({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
return (
<>
<ProductInfo id={id} />
<Suspense fallback={<p>Loading reviews…</p>}>
<Reviews id={id} />
</Suspense>
</>
);
}
The cached part becomes part of the static shell; reviews stream in behind Suspense.
Invalidate after a mutation
'use server';
import { updateTag } from 'next/cache';
export async function addProduct(data: FormData) {
await saveProduct(data);
updateTag('products'); // the next read sees fresh data
}
Rules of thumb
- Cache by default only what is shared between users. Do not cache output that depends on cookies or headers without passing them as arguments.
- Use short
cacheLifeprofiles first and lengthen them when you have measurements. - Tag everything you may need to invalidate.
Check the official docs for the exact APIs in your Next.js version, since caching APIs have evolved across 16.x releases.