Next.js Caching Expert Guidance
This skill provides expert-level guidance on Next.js caching behavior, focusing on the
directive, revalidation strategies, and Incremental Static Regeneration (ISR) patterns.
Core Mental Models
The "use cache" Directive
The
directive
marks a component or function as cacheable—it doesn't immediately cache anything. Caching happens at build time when Next.js writes the output to the cache store. This is a fundamental distinction that affects how you reason about cache behavior.
Automatic Static Rendering
Next.js automatically renders from top to bottom as deep as possible until it encounters something dynamic (like uncached data fetches). It then creates a "dynamic hole" for that content. You don't need to add
to every page—the framework handles partial static rendering automatically. Cached functions are NOT considered dynamic, so they don't create holes.
Two-Phase Rendering
Two renders occur during the build process:
- Warmup render (prospective render): Detects if dynamic APIs are used. Anything that doesn't resolve in a microtask is considered dynamic.
- Final render: Captures the actual output for the pre-rendered result.
Key Behaviors
ISR-Like Behavior
Adding
to a
page component makes it work like ISR—the entire output gets cached instead of having dynamic holes. Caches cannot be partial at the page level. To make a route ISR-like, add
to the main exported component (either at the top of the file or on the component itself).
Layout vs Page Caching
Setting
in a layout without setting it on the page does NOT make the page static. Each route segment controls its own caching behavior independently.
Suspense Boundaries with "use cache"
When you use
on a component with a Suspense boundary (containing components that fetch data), it works like ISR. The first request triggers the Suspense boundary, shows content, then caches the result for subsequent requests. If you want the Suspense boundary to show dynamic content every time, extract static parts into separate components with their own
directives (or use parallel routes).
Critical Distinctions
Revalidation APIs
- is conceptually similar to , with the argument being path-like
- revalidates in a stale-while-revalidate manner when used in server actions
- works as "read-your-own-writes" by purging the previous cache immediately, but cannot be used in route handlers
Cache Persistence
- persists across deployments
- does NOT persist across deployments
- Choose based on whether you need deployment-persistent caching
Common Patterns
Partial Page Caching
To cache only parts of a page while keeping others dynamic:
- Leave the page without
- Add to individual components
- Wrap dynamic components in Suspense boundaries as needed
- Alternative: Use parallel routes for the same effect
Sharing Cached Values
When you need a cached value from a layout in a page, cache the function output instead of the component. Call the function again in the page to retrieve the cached value.
Build-Time Snapshots
Every cacheable function gets a snapshot when called at build time. Using a
'd function in a dynamic component only guarantees a cache hit if that snapshot was captured at build time. Otherwise, it serves from in-memory cache.
API & Configuration Details
Dynamic API Replacement
Use
as a replacement for
.
Short Cache Behavior
Caches with a
configuration of less than 30 seconds are considered "short cache" and won't be included in runtime prefetch.
unstable_cache Functions
functions are considered instant (they don't create dynamic holes).
generateStaticParams Requirements
- Export at least one param in to actually generate a static shell for that route
- Without , dynamic pages fail because there's no Suspense boundary when reading params
- Workaround: Add a file or wrap the body in an empty Suspense boundary
- For ISR behavior on dynamic pages, always export at least one param from
- If no real param exists, return a placeholder and handle that case in component rendering
Deployment Architecture
The proxy that returns the static shell runs on the edge. It returns the shell immediately and continues the request for dynamic content. If a region goes down, the proxy continues working.
Verification
Static pages sometimes show as
in the build log. The most reliable way to verify a page is static is checking that
header equals
in the document request.
References
For comprehensive details, code examples, and deep-dives into each topic:
- references/detailed-guide.md — Full expanded guidance with all insights organized by topic. Consult this when you need detailed explanations, edge cases, or specific implementation patterns.