- Next.js
- Next.js Caching Architecture
- On-Demand Revalidation: revalidateTag vs revalidatePath
On-Demand Revalidation: revalidateTag vs revalidatePath
revalidateTag purges cache entries associated with a specific semantic cache key across the entire application, making it ideal for entity-based updates (e.g. updating a product). revalidatePath purges cached pages and route segments matching a URL path, making it ideal for page-level structural updates. Both invalidate the server Data Cache and Full Route Cache on-demand.
Learning Objectives
Select between revalidateTag and revalidatePath for specific mutation scenarios.
Explain how cache tagging enables surgical, multi-page cache purging from a single mutation.
Use revalidatePath with "page" vs "layout" segment types.
Trigger on-demand revalidation from webhook handlers (e.g. Headless CMS webhooks).
Prerequisites & Background Knowledge
Why Interviewers Care
A core system design question for e-commerce, CMS platforms, and multi-tenant applications where stale data directly impacts business operations.
The Challenge
Compare revalidateTag and revalidatePath. Demonstrate how to implement a CMS webhook handler that surgically invalidates cached product pages without purging unrelated routes.
Code Architecture & Implementation
1// app/api/webhooks/cms/route.ts2import { revalidateTag } from 'next/cache';3import { NextRequest, NextResponse } from 'next/server';45export async function POST(request: NextRequest) {6 // 1. Authenticate secret token to prevent unauthorized cache purging attacks7 const secret = request.headers.get('x-webhook-secret');8 if (secret !== process.env.CMS_WEBHOOK_SECRET) {9 return NextResponse.json({ message: 'Unauthorized' }, { status: 401 });10 }1112 const payload = await request.json();13 const { event, entity, id } = payload;1415 if (entity === 'product') {16 // Surgically purges every query tagged with this product ID17 // AND every list tagged with 'products'18 revalidateTag(`product-${id}`);19 revalidateTag('products-list');2021 return NextResponse.json({22 revalidated: true,23 tags: [`product-${id}`, 'products-list'],24 timestamp: Date.now(),25 });26 }2728 return NextResponse.json({ message: 'No action taken' });29}
Architectural Explanation
While revalidatePath("/products/123") only purges the cache at that specific URL, revalidateTag("product-123") purges all cached data tagged with that identifier regardless of which page or layout rendered it. In Next.js App Router, tagged fetches (fetch(url, { next: { tags: ["product-123"] } })) or "use cache" functions with cacheTag("product-123") allow single-point invalidation. When a webhook fires, Next.js marks that tag as stale. The next incoming visitor receives fresh data without a full site rebuild.
Common Mistakes & Anti-Patterns
Failing to authenticate webhook endpoints, leaving the application vulnerable to cache-busting denial of service (DoS) attacks.
Using `revalidatePath("/", "layout")` on every minor edit, unnecessarily blowing away the entire site cache.
Expecting revalidateTag to push real-time WebSocket updates to active browser windows (it is an invalidation mechanism, not a push notification).
Interview Follow-Up Traps
Interviewers will ask: "Does revalidateTag() trigger an immediate background render or wait for the next request?" Explain that Next.js uses stale-while-revalidate / lazy revalidation: the cache entry is marked stale immediately, and regenerated on the subsequent request.
Frequently Asked Questions
Can revalidatePath and revalidateTag be called from Client Components?
No. Both must be called in Server Actions or Route Handlers.
What is the performance overhead of calling revalidateTag frequently?
Purging tags is fast (metadata invalidation), but invalidating too frequently increases origin database load by forcing frequent re-renders.
