[stale-while-revalidate](<https://tools.ietf.org/html/rfc5861#section-3>) helps developers balance between immediacy—loading cached content right away—and freshness—ensuring updates to the cached content are used in the future. If you maintain a third-party web service or library that updates on a regular schedule, or your first-party assets tend to have short lifetimes, then
stale-while-revalidate may be a useful addition to your existing caching policies.
Support for setting
max-age in your
Cache-Control response header is available in Chrome 75 and Firefox 68.
Browsers that don't support
stale-while-revalidate will silently ignore that configuration value, and use
[max-age](<https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching#max-age>), as I'll explain shortly…
Let's break down
stale-while-revalidate into two parts: the idea that a cached response might be stale, and the process of revalidation.
First, how does the browser know whether a cached response is "stale"? A
[Cache-Control](<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control>) response header that contains
stale-while-revalidate should also contain
max-age, and the number of seconds specified via
max-age is what determines staleness. Any cached response newer than
max-age is considered fresh, and older cached responses are stale.
If the locally cached response is still fresh, then it can be used as-is to fulfill a browser's request. From the perspective of
stale-while-revalidate, there's nothing to do in this scenario.
But if the cached response is stale, then another age-based check is performed: is the age of the cached response within the window of time covered by the
If the age of a stale response falls into this window, then it will be used to fulfill the browser's request. At the same time, a "revalidation" request will be made against the network in a way that doesn't delay the use of the cached response. The returned response might contain the same information as the previously cached response, or it might be different. Either way, the network response is stored locally, replacing whatever was previously cache, and resetting the "freshness" timer used during any future
However, if the stale cached response is old enough that it falls outside the
stale-while-revalidate window of time, then it will not fulfill the browser's request. The browser will instead retrieve a response from the network, and use that for both fulfilling the initial request and also populating the local cache with a fresh response.
Below is a simple example of an HTTP API for returning the current time—more specifically, the current number of minutes past the hour.
In this scenario, the web server uses this
Cache-Control header in its HTTP response:
This setting means that, if a request for the time is repeated within the next 1 second, the previously cached value will still be fresh, and used as-is, without any revalidation.
If a request is repeated between 1 and 60 seconds later, then the cached value will be stale, but will be used to fulfill the API request. At the same time, "in the background," a revalidation request will be made to populate the cache with a fresh value for future use.
If a request is repeated after more than 60 seconds, then the stale response isn't used at all, and both fulfilling the browser's request and the cache revalidation will depend on getting a response back from the network.
Here's a breakdown of those three distinct states, along with the window of time in which each of them apply for our example: