6 min read
Effectively using ISR across industries and frameworks.
Incremental Static Regeneration (ISR) is a caching strategy that combines the perks of multiple rendering techniques to bring users dynamic content at cached speeds.
This guide explores how ISR fits into your overall caching strategy, how it can benefit your architecture, and how to implement it effectively. We'll compare ISR to traditional caching methods and provide real-world examples to illustrate its advantages.
Benefits of caching
Caching is a technique in web development that involves storing and reusing previously fetched or computed data. It helps improve website performance by:
Reducing server load: By serving cached content, fewer requests reach the server, allowing it to handle more traffic.
Saving bandwidth: Serving cached content reduces the data transferred between servers and clients, which can also decrease costs.
Decreasing latency: Cached responses are typically served much faster than generating new responses, resulting in quicker page loads, more responsive applications, and better user engagement.
Content availability: Cached content can remain available for end users even if providers go down.
Effective caching is key to build fast, scalable web apps.
ISR: A modern server-side caching strategy
ISR is a hybrid cache that combines the benefits of static site generation (SSG) and server-side rendering (SSR). It allows for:
Cached speeds with live content: Quickly serve edge-cached static content to users while updating data in the background. (This is known as "stale-while-revalidate" in HTTP caching.)
Selective regeneration: Update specific pages without rebuilding the entire site. This can significantly reduce build times, especially for content-heavy sites like Sonos.
On-demand invalidation: Trigger updates for specific pages as needed, such as when new content is published.
Guaranteed cache durability: Your data remains cached for the duration you specify. Only you or your team can invalidate this cache—unless it goes unaccessed for 31 days.
ISR pairs best with hybrid rendering frameworks, which allow you to create apps with some content prerendered (SSG) and some content served per request (SSR).
Too many acronyms?
Learn the differences between rendering strategies like SSG, SSR, CSR, ISR, and PPR—and see real-world examples of each.
Read More
ISR and modern web architecture
Caching requires careful configuration to work properly. Vercel's implementation of ISR uses framework-defined infrastructure, meaning there's no extra configuration outside your framework code.
Also, Vercel's ISR cache scales automatically with your traffic. Its asynchronous, serverless nature means it can be used without worrying about downtime. In fact, the cache can help prevent downtime by taking the load off your backend services to begin with. This can also reduce the costs of calling third-party APIs, such as AI providers.
ISR can act as a full replacement for HTTP caching at the edge. Instead of thinking about how to cache your application, you can focus on which pieces of your app would benefit from caching.
How ISR fits in the caching stack
Vercel enhances caching strategies with several approaches:
Static Assets: Automatically cached on Vercel's CDN, persisting across deployments if unchanged.
ISR: Vercel's solution for caching dynamic content not requiring real-time updates, leveraging the Edge Network for global low latency.
Application-level: For specific needs like storing frequently accessed data in memory (e.g., using Redis from the Vercel Marketplace).
Client-side: Recommended libraries like SWR optimize browser caching, minimizing network requests.
Combining these with ISR optimizes performance while maintaining up-to-date content.
Ready to try ISR yourself?
This demo of on-demand ISR in Next.js shows you the basics by revalidating displayed GitHub issues from a webhook.
Deploy Now
Framework adoption
Several popular frameworks currently support ISR:
If you don't see ISR in your favorite framework and want it, consider creating or upvoting a GitHub issue. Framework authors can implement ISR using Vercel's Build Output API.
Real-world scenarios where ISR shines
We don't want to have to say to a business stakeholder, "Hey, that typo that you want fixed on the homepage? It's going to take us hours to get that out, even though everything's already approved. So, the ability to incrementally statically regenerate only certain pieces of content—particularly when you have 10,000 pages of content—is a very important driver for us when evaluating and picking out a platform.
Ecommerce
Ecommerce sites with large inventories benefit greatly from ISR. For instance, Mecum, an online retailer with millions of assets and hundreds of thousands of pages, uses ISR to keep product information up-to-date without rebuilding the entire site.
When product details change (e.g., price, quantity on hand), only the affected pages are regenerated and re-cached. This ensures customers always see the latest information while maintaining fast page loads.
Stripe was also able to use ISR (in combination with client-side caching and static site generation) to serve a viral Black Friday micro-site with 17 million edge requests at launch.
News websites
News sites with frequently updating content are ideal candidates for ISR. News outlets like The Washington Post use ISR to serve breaking news quickly while efficiently managing server resources.
Hydrow uses ISR to update its blog every time a new article is published in their headless CMS. Users and authors always see the latest content, but the site only has to request data when a post updates.
AI-powered applications
Applications integrating AI can leverage ISR to optimize performance and costs. For example, a company using AI for product recommendations can cache the results of expensive AI computations with ISR.
The recommendations can be regenerated periodically or when the underlying data changes, ensuring users receive personalized content quickly without overloading the AI service or incurring unnecessary AI costs.
Leonardo.ai uses ISR to cache recent user-generated content, allowing visitors to see the latest content without waiting on a loading skeleton. This has also helped them drop build times from ten minutes to two.
How to implement ISR
ISR uses three invalidation techniques.
Time-based ISR
Time-based ISR regenerates pages at specified intervals. Use it when:
On-demand regeneration would be too frequent
Data sources lack webhook support
Content changes follow a predictable pattern
For example, using SvelteKit's implementation of ISR with the Vercel adapter, we could update a news homepage from a third-party API every 10 minutes:
import { error } from "@sveltejs/kit";import type { PageServerLoad } from "./$types";
export const load: PageServerLoad = async () => { try { const res = await fetch("<https://api.news.com/headlines>"); const headlines: any = await res.json();
return { headlines, // Revalidate every 10 minutes cache: { maxage: 600 }, }; } catch (err) { throw error(500, "Failed to fetch headlines"); }};
In SvelteKit, we use a +page.server.ts
file to handle server-side data fetching. The load
function fetches and returns data, which will be available to the page component. The cache
option sets the revalidation interval.
Be careful when using time-based ISR at too frequent an interval (60 seconds, for example). Although ISR can provide a needed buffer in severe traffic to help you save costs, revalidating too often—writing to the cache almost as often as you're reading from it—can be cost-inefficient, and you may need to rethink your strategy.
On-demand ISR
On-demand ISR regenerates pages in response to specific events. It's preferred to time-based because it:
Provides the most up-to-date content
Is more efficient, regenerating only when necessary
Allows for immediate updates to changes
For example, using Astro's on-demand ISR implementation you can revalidate an article page when you update the corresponding content in your CMS:
First, enable ISR in your Astro astro.config.mjs
:
import { defineConfig } from "astro/config";import vercel from "@astrojs/vercel/serverless";
export default defineConfig({ output: "server", adapter: vercel({ isr: { // Create a secret token for revalidation bypassToken: import.meta.env.VERCEL_REVALIDATE_TOKEN, }, }),});
Then, wherever your article fetch is happening:
---// ... your existing code ...
export const prerender = true;---
{/* ... your page content ... */}
Now, you can trigger revalidation by sending a GET
or HEAD
request to the page's URL with the x-prerender-revalidate
header:
curl -H "x-prerender-revalidate: <YOUR_BYPASS_TOKEN>" https://your-site.com/posts/my-article-slug
This will tell Vercel to revalidate the /posts/my-article-slug
page, ensuring the next visitor sees the fresh content. You can trigger this request from a webhook in your CMS or any other part of your application.
Tag-based ISR
Next.js supports tag-based revalidation for on-demand ISR. This allows you to invalidate multiple pages that share the same tag. Let's explore a real-world ecommerce example using a Server Component for a product page:
import { revalidateTag } from "next/cache";
async function getProduct(id) { // ... (fetch logic using tags: [`product-${id}`, "product-list"])}
export default async function ProductPage({ params: { id } }) { const product = await getProduct(id);
async function addToCart(formData) { const quantityToAdd = Number(formData.get("quantity")); if (quantityToAdd > 0 && quantityToAdd <= product.quantity) { await updateProductQuantity(id, product.quantity - quantityToAdd); revalidateTag(`product-${id}`); revalidateTag("product-list"); // ... (add to cart logic) } }
return ( <div> <h1>{product.name}</h1> <p>Price: ${product.price}</p> {product.quantity > 0 ? ( <form action={addToCart}> <input type="number" name="quantity" min="1" max={product.quantity} defaultValue="1" /> <button type="submit">Add to Cart</button> </form> ) : ( <p>Out of Stock</p> )} </div> );}
// Server-side function to update quantityasync function updateProductQuantity(id, newQuantity) { "use server"; // ... (update database logic)}
This approach improves efficiency by allowing you to update related product pages simultaneously. When a product's inventory is updated:
The specific product page is revalidated using the
product-${id}
tag.All pages listing multiple products (e.g., homepage, category pages) are revalidated using the
product-list
tag.
This ensures that inventory changes are reflected across the site for all users.
The future of ISR
ISR has been around for a few years now, and we've made a lot of observations of how it could be improved.
One of the most significant features currently in development is Partial Prerendering (PPR), which allows static and dynamic content to coexist at the component level. PPR can simplify the developer experience by reducing the number of concepts and rendering modes to consider.
While PPR is experimental, it's an exciting step forward in building dynamic web applications.
Takeaways
ISR is a powerful hybrid caching strategy that offers improved performance, reduced server load, and better scalability for modern web applications. By implementing ISR, you can serve static-like content with dynamic data freshness, enhancing user experience and SEO.
To get started with ISR on Vercel, check out our ISR template for a hands-on experience.