Incremental Static Regeneration: Merging Static Speed with Dynamic Freshness in Next.js
Learn how Incremental Static Regeneration in Next.js lets you keep static performance while refreshing pages on demand. Follow a concrete example, see the trade‑offs, and get actionable advice for production deployments.
18 Jul 2025, 02:07 UTC

The Stale Static Problem
When you build a Next.js site with getStaticProps, the framework pre‑renders every page at build time. That gives you blazing performance and SEO‑friendly URLs, but it also means that any change in your data source requires a full rebuild or a manual redeploy. For sites that pull from a CMS, a database, or an API that updates every few minutes, serving stale content can hurt user experience and search rankings.
ISR to the Rescue
Incremental Static Regeneration (ISR) lets you keep the static build benefits while allowing pages to refresh on demand. After you deploy a static page, Next.js will serve the cached version for a defined period. Once that period expires, the next request triggers a background rebuild of the page. The user sees the old content until the new version is ready, at which point subsequent requests receive the fresh page.
How It Works Under the Hood
- During a build, Next.js generates a static HTML file and a JSON payload containing the props.
- The
revalidatekey (in seconds) tells the runtime how long the cached page is considered fresh. - When a request arrives after the interval, Next.js serves the stale page and schedules a regeneration in the background.
- Once regeneration completes, the cache is swapped atomically, so subsequent visitors see the updated content without any downtime.
Implementing ISR in a Real Project
Below is a minimal example that demonstrates the core steps. The example assumes a Next.js 14 project with an external API that returns a list of blog posts.
1. Add revalidate to getStaticProps
export async function getStaticProps() {
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();
return {
props: { posts },
// Revalidate every 30 seconds
revalidate: 30,
};
}
Run this on a page like /posts. The revalidate value tells Next.js to keep the page fresh for 30 seconds.
2. Deploy to Vercel (or another platform)
On Vercel, the deployment automatically picks up ISR. After the initial build, the page will be served from the CDN cache. When the 30‑second window lapses, the next visitor triggers a background regeneration.
3. Verify Regeneration
Use the browser’s Network tab to inspect the x-nextjs-revalidate header. When you see this header set to 1, a regeneration just occurred. Alternatively, check the Vercel analytics dashboard for a spike in page build events.
Benefits at a Glance
- Zero downtime – the old page stays visible while the new one is built.
- SEO‑friendly URLs – the page remains static for crawlers.
- Reduced build times – you only rebuild pages that need updating.
- Predictable latency – the first request after a revalidate interval still receives a quick static response.
Trade‑offs & Limitations
Stale Window
The period between the revalidate expiry and the regeneration finish can still serve stale content. If your data changes very frequently, you might consider a shorter interval or fall back to getServerSideProps for those pages.
Dynamic Routes & Fallbacks
ISR works only for pages that use getStaticProps. Dynamic routes that use fallback: 'blocking' or fallback: true need careful handling: the first request may trigger a race condition if two users hit the page simultaneously. Use a flag in your data store or a short revalidate value to mitigate.
Serverless Costs
Each regeneration counts as a new function invocation on serverless platforms like Vercel. If you set revalidate to a very low value (e.g., 5 seconds) for many pages, you could see a spike in usage and cost. Monitor your analytics and adjust the interval to balance freshness and billable invocations.
Actionable Takeaways
- Start by adding
revalidateto pages that display data that changes every few minutes. - Choose an interval that matches your content cadence – 60 s for news, 300 s for blog archives.
- Monitor the
x-nextjs-revalidateheader and Vercel analytics to confirm regeneration is happening as expected. - If you need instant freshness for a particular page, combine ISR with a
useSWRhook on the client to poll for updates while the static page loads. - Keep an eye on serverless invocation counts; adjust
revalidateor switch togetServerSidePropsfor pages that demand real‑time data.
ISR gives you the best of both worlds: the speed of static sites and the flexibility of dynamic data. By carefully selecting which pages use it and monitoring the regeneration behavior, you can deliver fresh content without sacrificing performance or increasing build complexity.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.