Caching is one of the most important concepts to understand when building fast and scalable web applications. If you’re using Next.js, you already have powerful caching features built in.
What is Caching in Next.js?
Caching means storing the result of a computation (like fetched data or rendered HTML) so that it can be reused instead of recalculated.
In Next.js, caching can apply to:
- API responses
- Data fetched from databases
- Rendered pages
- Navigation payloads
Instead of rebuilding or refetching data on every request, Next.js reuses cached results when possible.
Caching helps:
- Improve page load speed
- Reduce server and API costs
- Scale to more users
- Improve Core Web Vitals
Caching Layers in Next.js 16
Next.js 16 uses multiple caching layers, but beginners should focus on the following four:
- Request Memoization
- Data Cache
- Full Route Cache
1. Request Memoization (Automatic)
When the same data is requested multiple times during a single render, Next.js automatically fetches it only once.
Example
async function getUser() {
return fetch("https://api.example.com/user").then(res => res.json());
}const userA = await getUser();
const userB = await getUser();
Even though getUser() is called twice, the request runs only once.
2. Data Caching with fetch
In Next.js 16, fetch is cached by default when used in Server Components.
Basic Cached Fetch example
const res = await fetch("https://api.example.com/posts");
const posts = await res.json();What happens?
- The response is cached
- Future requests reuse the cached data
- No repeated API calls
This is ideal for: Blog posts, Product lists, Documentation pages, Marketing content
- Content updates via webhooks
- Editors publish new content
- You need instant freshness
Caching isn’t just about speed; it's about efficiency, scalability, and user experience. Next.js gives you powerful tools from automatic memoization and static rendering to ISR and edge caching to build fast applications with minimal hassle.
Controlling Cache Behavior
Next.js gives you full control over caching using fetch options.
Cache Forever (Static Data)
await fetch(url, {
cache: "force-cache",
});Use this when the data rarely changes or content is static
Examples: Landing pages, Static CMS content
Disable Caching (Always Fresh Data)
await fetch(url, {
cache: "no-store",
});This forces a new request on every page load.
Use this for authenticated user data, payments, real-time dashboards, admin panels
Revalidate Data
await fetch(url, {
next: { revalidate: 60 },
});This means: Cache data for 60 seconds. After 60 seconds, refresh it in the background. This pattern is called Incremental Static Regeneration (ISR).
Best use cases: Blogs, News feeds, Product catalogs, CMS-driven sites
3. Full Route Cache (Page-Level Caching)
When a page uses cached data, does not read cookies or headers and does not use no-store then Next.js caches the entire rendered page.
Example
export default async function BlogPage() {
const posts = await fetchPosts();
return <BlogList posts={posts} />;
}If fetchPosts() is cached, the page HTML is cached too.
Static vs Dynamic Pages in Next.js 16
Understanding this distinction is critical.
Static Pages
- Rendered once
- Cached HTML
- Same for all users
Dynamic Pages
- Rendered per request
- Cannot be fully cached
- Still benefit from data caching
On-Demand Revalidation
Sometimes you want to manually invalidate cache when content changes (e.g., CMS updates).
Example API Route
import { revalidatePath } from "next/cache";
export async function POST() {
revalidatePath("/blog");
return Response.json({ revalidated: true });
}Use this when:
- Content updates via webhooks
- Editors publish new content
- You need instant freshness
Caching isn’t just about speed; it's about efficiency, scalability, and user experience. Next.js gives you powerful tools from automatic memoization and static rendering to ISR and edge caching to build fast applications with minimal hassle.
To read more about How to Build Your First API Endpoint in Next.js, refer to our blog How to Build Your First API Endpoint in Next.js.