Data fetching and caching in Next.js 16: Cache Components
How Next.js 16 caches: opt-in Cache Components with "use cache", cacheLife and cacheTag, static shells with dynamic holes (partial prerendering), revalidateTag vs updateTag vs refresh, and how this differs from Next 13–15.
Comes up in: React, Frontend system design
Learn#
Rohit’s team upgraded from Next.js 14 and could not explain why some pages showed day-old prices and others refetched everything. Caching in Next.js 13 to 15 was implicit. Fetch calls and routes were cached unless you opted out.
Next.js 16 flips that. With Cache Components enabled (cacheComponents: true), everything runs at request time unless you mark it with "use cache". You choose a lifetime with cacheLife and label entries with a cache tag via cacheTag, so you can invalidate them later:
async function ProductDetails({ id }: { id: string }) {
"use cache";
cacheLife("days");
cacheTag(`product-${id}`);
const product = await db.product.find(id);
return <Description product={product} />;
}Partial prerendering combines both: the cached parts form a static shell sent instantly, and dynamic parts, such as the price, stream in through Suspense holes.
Cache
- shell: name, images, description
State
empty
Network
empty
At build time, Next.js prerenders the product page. The description and images are marked "use cache", so they go into a static shell.
Read the steps as text
- At build time, Next.js prerenders the product page. The description and images are marked "use cache", so they go into a static shell.
- The price and stock are dynamic, wrapped in Suspense. They become holes in the shell.
- A request arrives. The shell is sent at once from the edge; the server renders price and stock and streams them in.
- An editor changes the description. updateTag('product-42') in the Server Action expires the cached entry, so the editor sees the change at once.
Predict#
Predict first
A user edits their profile name in a Server Action, then sees the page. Which call guarantees they see the new name immediately?
Revalidation with revalidateTag(tag, profile) is stale-while-revalidate: the next visitor may still get the old value while it refreshes. updateTag expires the entry and reads fresh data in the same request, which is what a user editing their own data expects.
Interview angle#
Say it like this — about 30 seconds
“In Next.js 16 with Cache Components, caching is opt-in. Code runs on each request unless it uses the use cache directive. I set how long with cacheLife, and label it with cacheTag. Partial prerendering sends a static shell from the cached parts and streams the rest through Suspense. To invalidate, revalidateTag serves stale data while it refreshes. In a Server Action, updateTag gives read-your-writes. This replaced the hidden fetch caching of Next 13 to 15.”
Follow-up How does caching work in the current Next.js version?
Follow-up What is partial prerendering?
Follow-up How do you keep secrets out of the client bundle in Next.js?
Follow-up When would you not use Next.js?
Practice#
On your own
Model the two invalidation styles: stale-while-revalidate with revalidateTag, and read-your-writes with updateTag.
Done when
- Fresh entries are reused; expired entries recompute on read.
- After
revalidateTag, the next read returns the old value once while storing a new one. - After
updateTag, the next read recomputes and returns fresh data.
Remember#
Try to answer each card before you open it. Then add them to your reviews.
Is caching on by default with Cache Components in Next.js 16?
No. Code runs per request unless marked "use cache".
revalidateTag vs updateTag?
revalidateTag: stale-while-revalidate. updateTag: read-your-writes, in Server Actions.
What is partial prerendering?
A static shell sent at once, with dynamic Suspense holes streamed in.
What does cacheTag do?
Labels a cached entry so it can be invalidated by tag later.
Go deeper
Four layers. Stop at the one your interview needs; each ends with a quick check.
The core ideaEvery round
cacheLife takes built-in profiles such as "hours", "days" or "max", or custom ones from next.config. Cache keys are generated from the function’s inputs by the compiler.
Check yourself: What does cacheLife('hours') control?
How long a "use cache" entry stays fresh and when it revalidates.
How it works underneathSenior rounds
revalidateTag(tag, profile) marks tagged entries stale and refreshes them in the background. updateTag(tag) and refresh() work only in Server Actions: the first expires entries for read-your-writes, the second re-renders uncached data Source: Next.js 16 release post.Check yourself: Which API refreshes uncached data shown elsewhere after an action?
refresh(), in a Server Action.
Edge cases and trapsWhere people slip
Cached functions must not read per-request data such as cookies or headers directly; read them outside and pass values as arguments, which become part of the cache key. Never cache per-user data under a shared key.
Check yourself: Can a "use cache" function read cookies directly?
No. Read request data outside and pass the values in as arguments.
In productionStaff-level answers
Check yourself: What changed about caching defaults from Next 15 to 16?
From implicit caching to opt-in Cache Components.
Finished the five steps? Mark it, and its cards join your reviews.
Last checked 2026-11-01. Spot a mistake? Use “Report an error” below — fixes are listed on the corrections page.
Interview questions this answers
- How does caching work in the current Next.js version?
- What is partial prerendering?
- How do you keep secrets out of the client bundle in Next.js?
- When would you not use Next.js?