What Revalidation Means in Next.js
Revalidation is the process of purging a stale cache entry — in the Data Cache or Full Route Cache — and regenerating it with fresh data, without requiring a full redeploy of the application. Next.js supports two complementary strategies: time-based revalidation, where a cached entry automatically expires and refreshes after a configured number of seconds, and on-demand revalidation, where your own application code explicitly tells Next.js 'this specific data just changed, throw away the cached version now.'
Cricket analogy: Like a groundskeeper who either re-rolls the pitch automatically every 24 hours on a schedule, or gets an urgent call to fix it immediately after unexpected overnight rain.
Time-Based Revalidation and ISR
Setting fetch(url, { next: { revalidate: 60 } }) or export const revalidate = 60 at the page level enables Incremental Static Regeneration: the first request after 60 seconds have elapsed still receives the stale cached page instantly, while Next.js regenerates the page in the background and swaps in the fresh version for subsequent requests — visitors are never blocked waiting on a rebuild. This stale-while-revalidate behavior means a slow upstream data source never directly slows down a user's page load, at the cost of occasionally serving data that's up to revalidate seconds old.
Cricket analogy: Like a scoreboard operator who keeps displaying the last known total instantly for fans while a runner is dashing to get the freshly updated number from the scorer's table.
// Time-based revalidation on a fetch call
async function getArticle(slug: string) {
const res = await fetch(`https://cms.example.com/articles/${slug}`, {
next: { revalidate: 60 },
});
return res.json();
}
// Or set it once for the whole page
export const revalidate = 60;On-Demand Revalidation: revalidatePath and revalidateTag
Calling revalidatePath('/blog/hello-world') from a Server Action or Route Handler immediately purges the Full Route Cache entry for that exact path, while revalidateTag('products') purges every Data Cache entry that was tagged with 'products' regardless of which route fetched it — making tags the better choice when one piece of data (like a product record) is rendered across multiple different pages. Both functions only take effect on the server; they don't reach into an individual visitor's client-side Router Cache, so a hard navigation or router.refresh() may still be needed to see the update immediately in an already-open browser tab.
Cricket analogy: Like an official scorer correcting one specific over's entry in the ledger the instant a no-ball is confirmed, versus reprinting every scorecard that has ever referenced that bowler's figures.
revalidatePath and revalidateTag only purge server-side caches. A browser tab that's already open may still show stale data from its Router Cache until the user navigates again or you call router.refresh() on the client.
Revalidating After a Server Action Mutation
The most common on-demand revalidation pattern pairs a Server Action that writes to a database with a call to revalidatePath or revalidateTag right after the mutation succeeds, so the UI reflects the change immediately after the form submits rather than waiting for a scheduled time-based refresh. Forgetting this step is the classic bug where a user submits a form, sees a success message, but the list below still shows the old data until they manually reload the page.
Cricket analogy: Like updating the scoreboard the instant a boundary is confirmed by the umpire, rather than leaving the old total up until the next scheduled scoreboard refresh at the over's end.
'use server';
import { revalidatePath } from 'next/cache';
export async function addComment(postSlug: string, formData: FormData) {
await db.comment.create({
data: {
postSlug,
body: formData.get('body') as string,
},
});
revalidatePath(`/blog/${postSlug}`);
}- Revalidation purges a stale cache entry and regenerates it, without a full redeploy.
- Time-based revalidation (ISR) serves a stale page instantly while regenerating it in the background.
- revalidatePath purges the Full Route Cache for one specific path.
- revalidateTag purges every Data Cache entry sharing that tag, across any route that fetched it.
- Neither revalidatePath nor revalidateTag reaches into a browser's client-side Router Cache.
- The standard pattern is to call revalidatePath or revalidateTag right after a Server Action's mutation succeeds.
- Forgetting to revalidate after a mutation is the classic cause of a form that 'saves' but doesn't visibly update the page.
Practice what you learned
1. What does time-based revalidation (ISR) do when a cached page's revalidate window has elapsed?
2. When should you prefer revalidateTag over revalidatePath?
3. Where is the standard place to call revalidatePath or revalidateTag after a mutation?
4. Does calling revalidatePath on the server automatically clear a stale entry in an already-open browser tab's Router Cache?
5. What is the classic bug caused by forgetting to revalidate after a Server Action mutation?
Was this page helpful?
You May Also Like
Caching in Next.js
A tour of the four caching mechanisms in the Next.js App Router — Request Memoization, the Data Cache, the Full Route Cache, and the Router Cache — and how they interact.
Server Actions Explained
Learn how Server Actions let you write server-side mutations that are callable directly from forms and Client Components, with progressive enhancement, pending states, and security considerations.
Route Handlers (API Routes)
Learn how to build server-side API endpoints in the Next.js App Router using route.ts files, the Web Request/Response APIs, dynamic segments, and their caching behavior.
Fetching Data in Server Components
Learn how to fetch data directly inside React Server Components using async/await, and how Next.js handles deduplication, parallelization, and streaming for those requests.
Related Reading
Related Study Notes in Web Development
Browse all study notesWebSockets Study Notes
Web Development · 30 topics
Web DevelopmentWebAssembly Study Notes
WebAssembly · 30 topics
Web DevelopmentgRPC Study Notes
Protocol Buffers · 30 topics
Web DevelopmentSpring Boot Study Notes
Java · 30 topics
Web DevelopmentFlask Study Notes
Python · 30 topics
Web DevelopmentDjango Study Notes
Python · 30 topics