- Next.js
- Next.js Caching Architecture
- Modern Explicit Caching with "use cache" & Cache Components
Modern Explicit Caching with "use cache" & Cache Components
In Next.js 16, Cache Components and the "use cache" directive introduce fine-grained, declarative caching at the component, function, or file level. Instead of configuring low-level HTTP fetch options, developers mark components or helper functions with "use cache", and configure retention using cacheLife() profiles and cacheTag() invalidation identifiers.
Learning Objectives
Implement component-level and function-level caching using the "use cache" directive.
Configure cache lifespans using cacheLife() profiles (e.g. "minutes", "hours", "days").
Assign cache invalidation tags using cacheTag() for targeted revalidation.
Explain how Cache Components work seamlessly with Partial Prerendering (PPR).
Prerequisites & Background Knowledge
Why Interviewers Care
The modern standard for Next.js 16 interviews. Demonstrates mastery of the latest state-of-the-art caching paradigm.
The Challenge
Explain how the "use cache" directive operates in Next.js 16. Demonstrate caching an entire component versus caching an individual database helper function, and configure cacheLife and cacheTag.
Code Architecture & Implementation
1// app/components/TrendingProducts.tsx2import { cacheLife, cacheTag } from 'next/cache';3import { db } from '@/lib/db';45// Next.js 16: "use cache" caches the rendered RSC output of this component!6export async function TrendingProducts() {7 'use cache';8 cacheLife('hours'); // Retain for hours according to configured profile9 cacheTag('products', 'trending-products'); // Revalidation tag1011 const products = await db.query.products.findMany({12 where: (p, { eq }) => eq(p.isTrending, true),13 limit: 6,14 });1516 return (17 <section className="grid grid-cols-3 gap-4">18 {products.map((item) => (19 <div key={item.id} className="border p-4 rounded">20 <h3>{item.name}</h3>21 <p>${item.price}</p>22 </div>23 ))}24 </section>25 );26}
Architectural Explanation
Historically, Next.js caching was tightly coupled to the fetch() API. If you queried a database via Prisma, you could not easily cache it in the Data Cache without complex custom wrappers. The "use cache" directive abstracts caching away from the transport layer. Placing "use cache" inside an async function or Server Component instructs Next.js to serialize the return value (or RSC tree) into the cache. Combined with cacheLife() (which defines stale, revalidate, and expire thresholds) and cacheTag(), it provides complete control over data freshness.
Common Mistakes & Anti-Patterns
Using "use cache" inside a Client Component (it is strictly a server-side directive).
Passing non-serializable arguments (like database connection instances or request callbacks) to cached functions.
Confusing "use cache" with React’s "use server" directive.
Interview Follow-Up Traps
The interviewer asks: "What happens if a component with use cache reads from cookies()?" Next.js will throw an error during build/render because cached components cannot depend on un-cached per-request dynamic data unless parameterized properly.
Frequently Asked Questions
Does "use cache" replace React.cache()?
No. `React.cache()` is per-request memoization. `"use cache"` is persistent cross-request caching stored in the Next.js cache store.
How do you enable "use cache" in Next.js 15/16?
In Next.js 16, enable it via `cacheComponents: true` (or `partialPrefetching: true`) in next.config. In earlier Next.js 15 canary releases, it was configured via `experimental: { dynamicIO: true }`.
