What Is `stale-while-revalidate`? A Simple Guide to Faster Web Performance

What Is `stale-while-revalidate`? A Simple Guide to Faster Web Performance

Learn stale-while-revalidate caching for instant web performance. Serve cached content immediately while updating in background.

Modern sites need to feel instant. Users shouldn’t wait while your server prepares fresh data. This is where stale-while-revalidate shines. It lets caches serve old content immediately while they fetch a fresh version in the background.

It’s one of the best tricks for fast, resilient web apps.


What Does stale-while-revalidate Do?

You add it inside your Cache-Control header:

Cache-Control: max-age=60, stale-while-revalidate=300

Meaning:

  • If the response is fresh (within 60 seconds), serve it normally.
  • If it’s stale, the cache can still serve it instantly for up to 300 seconds.
  • Meanwhile, the cache fetches a new version behind the scenes.

Users get fast responses, and your server updates quietly.


Why It’s So Useful

1. Instant page loads

Even if your API or server is slow at the moment, users see cached content right away.

2. Fewer origin server hits

Your server gets hammered far less, especially during peak traffic.

3. Zero downtime resiliency

If your backend has a hiccup, caches can still serve the stale copy. Your app feels “up” even if something is broken.

4. Perfect for content that updates often

Dashboards, news feeds, product lists… Users get good performance and reasonably fresh data.


How It Works Step by Step

Let’s say:

Cache-Control: max-age=60, stale-while-revalidate=300

User visits at:

  • 00:00–01:00 → Cache is fresh → served fast.
  • 01:01–06:00 → Cache is stale → still served instantly + background refresh.
  • After 06:00 → Too stale → cache must fetch a new version before serving.

This balance gives speed without sacrificing freshness.


Where It's Most Useful

  • SPAs with API calls
  • Next.js / React apps with static JSON data
  • CDN-cached HTML (Vercel, Cloudflare, Fastly)
  • Product catalogs
  • User dashboards
  • News / articles
  • Public API endpoints

It’s basically a free performance boost.


Examples

Express.js

app.get("/feed", (req, res) => {
  res.set("Cache-Control", "public, max-age=60, stale-while-revalidate=300");
  res.json({ items: [] });
});

Nginx

add_header Cache-Control "public, max-age=60, stale-while-revalidate=300";

Go

w.Header().Set("Cache-Control", "public, max-age=60, stale-while-revalidate=300")

Best Practices

  • Keep max-age short for fast-changing data.
  • Keep stale-while-revalidate longer to reduce server load.
  • Combine with ETag for strong validation.
  • Don’t use it for private or sensitive data.

Conclusion

stale-while-revalidate makes your app feel instant while still staying fresh in the background. It’s one of the easiest, most impactful caching optimizations you can apply—especially on CDNs.


Album of the blog: