If you have built an application using the Next.js App Router, there is a 100% chance you've come across the issue of updating the database but the page still showing the old data.
Welcome to the Server-Side Caching paradigm.
In the React SPA world, if a user hits refresh, the cache is wiped clean. Next.js flipped the script. It caches data on the Server, and by default, it caches everything, aggressively.
To understand why your app is behaving the way it is we'll look at some concepts to understand how the Next.js cache actually works:
The Bakery Analogy (API Data vs Pages)
Think of your Next.js application as a Bakery.
The API Data (The Data Cache) will be our raw ingredients (flour, sugar, eggs) fetched from your database or external APIs.
The Pages (The Full Route Cache) will be the fully baked cake sitting in the display window.
Next.js doesn't just cache the finished HTML (cake), it also caches the raw JSON (ingredients). This means if 50 users from different location visit your site at the exact same time, Next.js doesn't overwhelm your database with 50 queries. It uses the cached ingredients to serve everyone instantly.
The 4 Layers of Caching
The most common point of confusion is what happens when a user hits the refresh button. Let's break down the four layers of the Next.js cache using our kitchen
This now leads us to the 4 layers of caching when dealing with Next.js:
1. Request Memoization (The Countertop/Clipboard)
If three different React components on the same page all call fetch('/api/user'), Next.js deduplicates them. It only makes the network request once and shares the result.
NOTE: The countertop/clipboard is wiped clean after every single page render.
2. Router Cache (The Customer's Plate)
As a user clicks around your app, Next.js stores the React Server Component payloads in the browser's memory. This makes clicking the Back button feel instantaneous.
NOTE: This doesn't survive a refresh either, a hard refresh wipes the browser's memory (washes the plate).
3. Data Cache (The Pantry)
This is where Next.js stores the raw JSON data returned from your database across multiple user sessions.
NOTE: This survives a refresh, if you refresh the page, the browser asks the server for new data, but the server just pulls the same cached data from the pantry.
This is why refreshing often doesn't "fix" stale data!
4. Full Route Cache (The Display Window)
Next.js takes the cached data and your components, rendering them into pure, static HTML at build time.
NOTE: This survives a refresh as it serves the pre-rendered HTML file until the underlying data cache is explicitly invalidated.
Taking Control of the Cache
Caching is fantastic for performance, but dynamic apps need dynamic data. Here is how you take control and tell Next.js to throw away the old ingredients.
1. Opting Out Entirely (No Caching)
If a piece of data changes constantly (like a live stock ticker or bank account balance), tell Next.js not to cache the fetch request at all:
// Fetched fresh on every single request
const res = await fetch('https://api.example.com/data', {
cache: 'no-store'
});
2. Time-Based Revalidation (Stale-While-Revalidate)
Tell Next.js to keep the cache for a specific amount of time before fetching fresh data in the background:
// Revalidate this data every 3600 seconds (1 hour)
const res = await fetch('https://api.example.com/data', {
next: { revalidate: 3600 }
});
3. On-Demand Revalidation (The "Invalidate" Button)
When a user submits a form (like updating their profile), you need to instantly clear the cache for that specific page. You do this inside a Server Action:
'use server'
import { revalidatePath } from 'next/cache';
export async function updateProfile(formData) {
await db.user.update(formData);
// Tell Next.js to throw away the cached HTML and data for this route
revalidatePath('/profile');
}
The Grand Finale
Over these 5 articles, we went from understanding the theory of "Fresh vs Stale" to mastering HTTP headers, taming React-Query/Redux client state and finally conquering the Next.js server cache.
Caching is no longer just a backend optimization. It is the beating heart of the frontend User Experience. Master it, and you will build applications that are absolutely instantaneous and save server cost
Now go build something fast.
Top comments (0)