FrontendPrep
Menu
Topics
Questions
Guides
Challenges
Soon
Back to Next.js Questions
nextjsHard

Next.js: Data Fetching, Caching, and Revalidation

Understand data fetching in Next.js App Router. Learn about server-side fetch extensions, request memoization, data caching, opt-out strategies, and ISR revalidation.

Next.js: Data Fetching, Caching, and Revalidation

One of the most complex advanced questions in a Next.js interview is:

How does Next.js cache data, and what are the four levels of caching in the App Router? How do you configure request memoization, data caching, and dynamic revalidation?

Next.js extends the native JavaScript fetch API to provide server-side caching, request memoization, and automated page revalidation. Understanding how these layers interact is vital for optimizing performance and preventing stale content.


1. The Four Cache Layers

Next.js uses a multi-layered cache model to minimize database lookups and API calls.

    Client Request


 ┌───────────────┐
 │ Request Memo  │  (Renders identical fetches within a single render pass)
 └───────┬───────┘
         │ Cache Miss

 ┌───────────────┐
 │ Data Cache    │  (Persists fetched JSON data across requests and server restarts)
 └───────┬───────┘
         │ Cache Miss

 ┌───────────────┐
 │ Full Route    │  (HTML & RSC Payload caching for static route segments)
 │ Cache         │
 └───────┬───────┘
         │ Cache Miss

 ┌───────────────┐
 │ Router Cache  │  (In-memory client-side cache for layouts and pages during navigation)
 └───────────────┘

2. Deep Dive: The Caching Mechanisms

A. Request Memoization

If you call the same API endpoint using the same parameters in multiple Server Components in a single request, Next.js automatically deduplicates the calls.

  • Scope: Single HTTP request life-cycle.
  • Opt-out: Use AbortController or pass { cache: 'no-store' }.
// Even if this function is called in Header, Footer, and Sidebar, 
// the HTTP request runs ONLY once.
async function getUser() {
  const res = await fetch('https://api.example.com/user');
  return res.json();
}

B. Data Cache

Next.js stores data fetched from external systems.

  • Scope: Persistent across multiple requests and user sessions.
  • Storage: Flat files in .next/cache or external caches.
  • Opt-out: Pass { cache: 'no-store' } to the fetch options.
// Fetches and caches indefinitely
const res = await fetch('https://api.example.com/data', { cache: 'force-cache' });

3. Revalidating Cached Data

To refresh cached data, Next.js provides two types of revalidation (Incremental Static Regeneration):

A. Time-based Revalidation

Refreshes data after a specific interval.

// Revalidate this fetch at most every 60 seconds
const res = await fetch('https://api.example.com/posts', {
  next: { revalidate: 60 }
});

B. On-demand Revalidation

Refreshes data manually via a tags system or path trigger, ideal for updating content immediately when database mutations occur (e.g. headless CMS webhook callbacks).

// Fetch data and tag it
const res = await fetch('https://api.example.com/products', {
  next: { tags: ['products-list'] }
});

To purge the cache inside a Server Action or Route Handler:

import { revalidateTag, revalidatePath } from 'next/cache';
 
async function updateProduct() {
  'use server';
  await saveProductToDb();
  // Trigger on-demand cache clear
  revalidateTag('products-list'); 
}

4. Opting Out of Caching (Dynamic Rendering)

Next.js automatically statically generates routes unless you explicitly use dynamic functions or opt-out in settings:

  • Dynamic Functions: Accessing cookies(), headers(), or searchParams on pages forces the route to render dynamically on every request.
  • Segment Config: You can define route-level configurations directly:
    export const dynamic = 'force-dynamic'; // Equivalent to getServerSideProps

Key Takeaways

  • Deduplication: Request memoization is automatic for fetch calls, preventing duplicate network queries on a single render tree.
  • Data Cache persistence: Data cache is preserved between deployments unless invalidated by revalidation tags.
  • Route revalidation: Use revalidateTag() to purge specific fetch data selectively rather than rebuilding whole page paths.
  • Router Cache: Client-side navigation caches segments in browser memory temporarily (30s for dynamic, 5m for static).

Share this Resource

Help other developers level up by sharing this study guide.

More Technical Questions

Expand your mastery. Deep dive into other frontend interview challenges in this category.