Incremental Static Regeneration (ISR)

Master ISR — the Next.js feature that gives you static performance with dynamic freshness. Learn time-based and on-demand revalidation for real production systems.

Last reviewed: January 2025

·Next.js 13Next.js 14Next.js 15
✅
Quick Understanding: ISR lets you pre-build static pages that automatically refresh in the background after a set time. Users always get fast static HTML. After the revalidation window expires, the next request triggers a background rebuild. The stale page is served while the fresh one is being built.

🔍 What Is It?

Incremental Static Regeneration (ISR) is a hybrid between SSG and SSR:

  • →Pages are pre-built as static HTML (like SSG) — fast CDN delivery
  • →After a revalidation period, the next request triggers a background rebuild
  • →The stale page is served while the fresh page is being built (stale-while-revalidate)
  • →Once rebuilt, the fresh page replaces the stale one for subsequent requests

Two types of ISR:

  1. Time-based — revalidate every N seconds (next: { revalidate: 3600 })
  2. On-demand — trigger revalidation via revalidatePath() or revalidateTag() from a webhook

🎯 Why Do We Need It?

SSG is fast but stale. SSR is fresh but slow. ISR gives you both:

  • →Static performance — CDN-served HTML, no server per request
  • →Dynamic freshness — pages update automatically, no full rebuild needed
  • →Scalable — only the changed pages rebuild, not the entire site
  • →On-demand — CMS publish triggers immediate page update, not a full deploy

Without ISR, a 10,000-page product catalog would need either:

  • →A full rebuild on every product change (slow CI/CD), or
  • →SSR for every request (expensive at scale)

🏗️ What Happens in Real Projects?

ISR patterns in production:

  • →Product pages — revalidate: 3600 (hourly) for prices and stock
  • →Blog posts — on-demand revalidation from CMS publish webhook
  • →News articles — revalidate: 300 (5 min) for breaking news sections
  • →Homepage — on-demand revalidation when featured content changes
  • →Documentation — on-demand revalidation on Git push

Real example: An e-commerce site with 200,000 products uses ISR with revalidate: 3600. When a product price changes, a webhook calls revalidatePath('/products/[slug]') for just that product — no full rebuild needed.

⚙️ How It Works

Time-based ISR flow:

  1. Build time: page is pre-rendered as static HTML
  2. Request 1 (within revalidation window): CDN serves cached HTML instantly
  3. Revalidation window expires (e.g., 60 seconds)
  4. Request 2 (after window): CDN serves stale HTML AND triggers background rebuild
  5. Background rebuild: Next.js re-runs the Server Component, fetches fresh data
  6. Request 3+: CDN serves the newly built HTML

On-demand ISR flow:

  1. CMS editor publishes a new blog post
  2. CMS sends a webhook to /api/revalidate?tag=blog
  3. Route Handler calls revalidateTag('blog')
  4. Next.js invalidates all pages tagged with 'blog'
  5. Next request to any blog page triggers a fresh rebuild

💻 Example

Time-based and On-demand ISR — Both ISR patterns used together in a content-heavy application.

tsx
// app/products/[slug]/page.tsx
export default async function ProductPage({ params }: { params: { slug: string } }) {
  const product = await fetch(
    `https://api.example.com/products/${params.slug}`,
    {
      next: {
        revalidate: 3600, // Revalidate every hour
        tags: ['products', `product-${params.slug}`], // Tag for on-demand revalidation
      },
    }
  ).then((r) => r.json());

  return (
    <div>
      <h1>{product.name}</h1>
      <p className="price">£{product.price}</p>
    </div>
  );
}

// Route is static at build time, revalidated every hour

🤔 Common Confusions

❓ Does ISR guarantee fresh data within the revalidation window?

No — ISR uses stale-while-revalidate. A user might see data that is up to (revalidation period + rebuild time) old. For most content (product descriptions, blog posts), this is acceptable. For truly real-time data (stock prices, live inventory), use SSR.

❓ What is the difference between revalidatePath and revalidateTag?

revalidatePath invalidates a specific URL path (e.g., /products/my-product). revalidateTag invalidates all pages that used fetch() with that tag. Tags are more flexible — one CMS publish can revalidate multiple pages (the product page, the category page, the homepage) with a single revalidateTag call.

❓ Does ISR work outside of Vercel?

Time-based ISR works on any Node.js host — Next.js handles it internally. On-demand ISR (revalidatePath/revalidateTag) also works on any host. However, the caching infrastructure on Vercel is more sophisticated (global CDN invalidation). On self-hosted setups, caching is per-server-instance.

🚨 Common Production Issues

Cache stampede — when a popular page's revalidation window expires, multiple simultaneous requests can all trigger a rebuild. Next.js deduplicates this, but under extreme load, configure a distributed cache (Redis) as the ISR cache store.

On-demand revalidation not working — revalidatePath and revalidateTag must be called from a Server Action or Route Handler, not from a Client Component. Also ensure the path matches exactly — revalidatePath('products/slug') without leading slash will not work.

ISR and personalised content — never use ISR for user-specific pages. ISR serves the same cached HTML to all users. A logged-in user would see another user's data. Use SSR for personalised content.

✅ Best Practices

Tag all fetch calls with meaningful tags — enables precise on-demand revalidation

Use on-demand ISR for CMS-driven content — pages update the moment editors publish

Set revalidate based on how stale the content can be, not how often it changes

Combine time-based (safety net) with on-demand (immediate) revalidation

Never use ISR for user-specific or personalised content — use SSR

🏛️ Architect's Note

Senior Architect's Perspective

ISR is one of Next.js's most powerful and underused features. The combination of time-based + on-demand revalidation gives you a content delivery architecture that rivals dedicated CDN + CMS setups at a fraction of the complexity.

For enterprise content platforms: design your revalidation strategy upfront. Map every content type to a revalidation strategy: static (never changes), ISR-time (changes occasionally), ISR-on-demand (changes on publish), SSR (changes per user). This mapping becomes your caching architecture.

💬 Frequently Asked Questions

What is the minimum revalidation time?

Next.js enforces a minimum of 1 second. In practice, use at least 60 seconds for most content. Very short revalidation times (< 60s) approach SSR performance characteristics — you might as well use SSR at that point.

How do I revalidate a layout that is shared across many pages?

Layouts are not independently revalidated — they revalidate with their child pages. To revalidate navigation that appears in a layout, use revalidateTag on the tag used by the layout's fetch call. All pages sharing that layout will get fresh navigation data.

Can I use ISR with database queries (not just fetch)?

Yes — use unstable_cache from next/cache to wrap database queries. It provides the same revalidation semantics as fetch. Example: const getCachedUser = unstable_cache(async (id) => db.user.findUnique({ where: { id } }), ["user"], { revalidate: 3600, tags: ["users"] })

🎯 Key Takeaways

1ISR = static performance + dynamic freshness — the best of SSG and SSR
2Stale-while-revalidate: users get fast cached HTML, rebuild happens in the background
3Time-based ISR: set revalidate in seconds on fetch calls
4On-demand ISR: call revalidatePath() or revalidateTag() from webhooks
5Tag fetch calls for precise on-demand invalidation of specific content
6Never use ISR for personalised/user-specific content — use SSR

🎯 Practice this topic in interviews

↗ Where this topic fits

Sources

Sources / References

Use these Next.js references to verify the concept in official docs and continue into the most relevant SplashRide pages.

Related SplashRide pages

SplashRide Next.js learning path

Browse the full Next.js topic collection and learning order on SplashRide.

Next.js Interview Prep

Practice Next.js interview questions and scenario-based answers.

Frontend Engineer Career Path

A beginner-friendly journey through web foundations, React, production frontend engineering, and interview preparation.

Full Stack Java Developer Career Path

A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.

Static Site Generation (SSG)

Master Static Site Generation in Next.js — pre-building pages at deploy time for maximum performance, CDN delivery, and zero server costs.

Server-Side Rendering (SSR)

Understand Server-Side Rendering in Next.js — when to use it, how it works with the App Router, and how to avoid the performance traps that catch most developers.