Caching and Revalidation
Next.js optimizes performance by caching data aggressively. It manages a multi-layer cache that spans request lifecycles, database operations, static pages, and client-side router transitions.
1. The Four-Layer Cache Architecture
Here is how Next.js handles caching across the lifecycle:
- Request Memoization: Caches duplicate fetch requests with identical URLs and parameters within a single server request lifetime. This allows you to call the same fetch function in multiple components without paying a performance penalty.
- Data Cache: Persists data across user sessions and server restarts until manually invalidated.
- Full Route Cache: Stores the compiled HTML and React Server Component payload of static pages at build time.
- Router Cache: Client-side memory cache that stores visited routes in the browser during a user session, ensuring immediate back-and-forth navigation.
2. Configuring Cache Behavior
You can customize fetch cache behavior using the standard fetch configuration options:
// 1. Cache the response globally (Default behavior)
fetch("https://api.example.com", { cache: "force-cache" });
// 2. Disable cache completely, fetching live data on every call
fetch("https://api.example.com", { cache: "no-store" });
// 3. Cache the response for a specific time limit (in seconds)
fetch("https://api.example.com", { next: { revalidate: 3600 } });3. On-Demand Revalidation
Sometimes you need to purge the cache instantly when database records change (for example, when a user edits an article or submits a product review). Next.js supports on-demand revalidation using two API helpers:
Revalidating by Path
Clears the cache for a specific route path:
import { revalidatePath } from "next/cache";
// Purge cache for all users visiting the blog overview page
revalidatePath("/blog");Revalidating by Tag
A cleaner approach is grouping fetch requests using a custom cache tag, and then invalidating that tag:
// Step 1: Assign a custom tag to your fetch request
fetch("https://api.example.com/products", {
next: { tags: ["product-list"] }
});
// Step 2: Trigger revalidation elsewhere (e.g., in a Server Action)
import { revalidateTag } from "next/cache";
async function handleNewProductSubmit() {
// Purges only the database cache matching this tag
revalidateTag("product-list");
}Published on Last updated: