Most caching directives trade freshness against speed. stale-while-revalidate refuses the trade: serve the stale copy now, fetch a fresh one in parallel, and let the next visitor benefit. Understanding its mechanics tells you exactly when that refusal is safe.
The execution sequence
A request arrives after max-age expired but inside the SWR window. The cache responds immediately with the stale object, tagging it appropriately, and simultaneously issues one asynchronous revalidation to origin. The requesting user pays zero revalidation latency; the refresh completes out of band; subsequent requests get the fresh copy. Crucially, well-implemented caches collapse concurrent revalidations into a single origin fetch, so a stampede of stale hits produces one background request, not a thundering herd.
The guarantee, stated precisely
SWR bounds staleness, it does not eliminate it: your users may see content up to max-age plus the SWR window old. That bound is the entire design question. Sixty seconds of max-age with an hour of SWR means an hour-old page in the worst case, which is fine for a product listing and unacceptable for a price during a flash sale. Write the acceptable-staleness number down per content class before choosing windows, not after the incident review.
The origin-load arithmetic deserves a paragraph, because it surprises people. Without SWR, every expiry is a synchronous revalidation on some unlucky user’s critical path, and expiries cluster at popular-object boundaries. With SWR plus request coalescing, origin fetch rate approaches one per object per TTL window per shield regardless of traffic, and the fetches move off every user’s path entirely. On a high-traffic site, that converts revalidation from a percentage of all requests into a rounding error, which shows up simultaneously in p95 latency and the origin bill.
Vendor variance that bites
Support is not uniform: some CDNs honor the directive natively, some implement equivalent behavior through proprietary settings, and browser support governs only the browser cache layer. Background-refresh behavior under load, whether revalidations are coalesced, queued or dropped, differs by implementation, and it is precisely the behavior that matters during your worst traffic hour. Test it with a load tool, not the documentation.
In practice
Deploy SWR first on HTML shells and API GETs whose data tolerates minutes of lag: the latency win is immediate and the risk negligible. Pair it with stale-if-error at a longer window so origin trouble degrades to slightly-old content instead of errors. Then instrument age headers in your RUM so you know the staleness your users actually experience, which is invariably lower than the worst case and worth being able to prove.
We tune SWR windows against measured content-change rates as part of cache engagements. Bring change logs; leave with numbers.
