CACHE
COMPONENTS
The evolution of Partial Prerendering. Break your application into granular Surgical Zones that can be individually cached, revalidated, or streamed dynamically.
The Behavior Shift
Next.js 16 moves from an "Opt-out" model to a "Strictly Static" model. This ensures performance is predictable and prevents accidental dynamic rendering of large portions of your app.
Full-Page Re-rendering
- ✕ Layouts re-render on every single request.
- ✕ Zero CDN caching for the HTML shell.
- ✕ High TTFB (Time to First Byte) because server waits for all data.
- ✕ Personalization kills performance for the entire route.
The "One-Speed" Route
Entire response is blocked by the slowest dynamic fetch
The "Two-Speed" Mechanism
- ✓ Layout Shell is served instantly from the Global CDN.
- ✓ Static parts are pre-rendered at build time.
- ✓ Dynamic "Holes" stream independently once data is ready.
- ✓ Personalization is isolated to specific components.
The "Multi-Speed" Route
Mechanics of the Request
1. How Layouts are Cached
In the old model, a Navbar with cookies() forced the whole page dynamic. Now, the Navbar itself can be marked with 'use cache'. The compiler extracts the static HTML of the Navbar links and logo, storing them on the CDN.
export default function Navbar() {
return <nav>...</nav>
}
2. Handling Dynamic Edge Cases
What if the Navbar needs the User Name? We wrap only the name in Suspense. The user sees the Navbar instantly from the CDN, then the name "pops in" via streaming.
<UserName /> // Only this is dynamic
</Suspense>
The Unified Secret: One route, two delivery methods. The static bytes travel via HTTP/2 immediately, followed by the dynamic bytes over the same connection. This is why your Layouts never "flicker" anymore—they are already there.
Surgical Zone Sandbox
Zone 1: Static Shell
Calculated at build-time. This content is identical for all users and served instantly from the edge CDN.
Status
PRERENDERED
Latency
0ms
Zone 2: Cached Output
This component uses 'use cache'. It is cached globally and shared across all user requests.
Current State
Refreshed
07:29:14 PM
On-Demand Revalidation
Server ActionUpdate the simulated "Database" and trigger a revalidateTag to see Zone 2 update while Zone 1 stays static.
Global Persistence
Data fetched in a 'use cache' block is cached 1:N. The first visitor triggers the computation; subsequent visitors receive the pre-rendered HTML/RSC payload instantly.
Streaming Boundaries
In Next.js 16, dynamic logic is isolated to its nearest Suspense boundary. This allows the rest of the page to remain a static shell even when personalization is required.
Precision Invalidation
Time-based caching (TTL) is never enough for real-time apps. Learn how to bridge the gap between "Static Speed" and "Live Data" using surgical tag invalidation.
The Stale Data Problem
If you set cacheLife('hours'), your users might see old prices or stock levels for up to 60 minutes. In a high-traffic app, this leads to lost revenue or synchronization errors. Surgical Invalidation allows you to keep the 1-hour cache but "kill" it the second data changes.
1. Set the Tag
'use cache';
cacheTag('prices'); // Subscribe
return await getPrice();
}
2. Trigger the Event
async function updatePrice() {
await db.save();
revalidateTag('prices'); // Notify
}
Real-World Use Cases
E-commerce Pricing
Instantly update sales across thousands of edge nodes the moment you hit "Publish" in your CMS.
Inventory Sync
When a stock hits zero, trigger a global invalidation so users never see an "In Stock" button for an empty shelf.
User Permissions
When a user upgrades their plan, revalidate the "Permissions" tag so they get access to PRO features immediately.
The "Real-time" Pipeline
By connecting Database Webhooks (from Supabase, Prisma, or Sanity) to a Next.js Route Handler that calls revalidateTag, you transform your static application into an event-driven engine. You get the 1ms response time of the Edge with the freshness of a real-time database.
Architecture Guide
Next.js 16 Caching Philosophy
Compiler Tip
Next.js uses static analysis to determine which components can be cached. Use 'use cache' to override defaults.
Stable PPR
No more experimental flags. PPR is now the foundation of the Cache Components model.
Granular TTL
Set cache duration per-component with cacheLife('minutes') or custom presets.
Tagging System
Connect frontend fragments to backend database tags for sub-second invalidation.