As pointed out by @DanilaVershinin in his answer, s-maxage
and stale-while-revalidate
are applied to different caches - shared cache and browser cache respectively. They do not overlap with each other.
Disclaimer: this answer applies to max-age
(and not s-maxage
).
Setting the page's Cache-Control
header to max-age=3600, stale-while-revalidate=59
means two things:
- The page is considered fresh for 3600 seconds (
max-age=3600
);
- The page will continue to be served from stale up to 59 seconds after that (
stale-while-revalidate=59
) while revalidation is done in the background.
stale-while-revalidate
does not get ignored, it determines the extra time window when revalidation occurs after the page's max-age
has passed (i.e. when the page is stale).
Here's the cache states across the three time windows (based on https://web.dev/stale-while-revalidate/#live-example):
0 to 3600s |
3601s to 3660s |
After 3660s |
Cached page is fresh and used to serve the page. No revalidation. |
Cached page is stale but used to serve the page. Revalidation occurs in the background to populate cache. |
Cached page is stale and not used at all. New request is made to serve the page and populate cache. |
Excerpt from the HTTP Cache-Control Extensions for Stale Content spec:
Generally, servers will want to set the combination of max-age
and
stale-while-revalidate
to the longest total potential freshness
lifetime that they can tolerate. For example, with both set to 600,
the server must be able to tolerate the response being served from
cache for up to 20 minutes.
Since asynchronous validation will only happen if a request occurs
after the response has become stale, but before the end of the
stale-while-revalidate
window, the size of that window and the
likelihood of a request during it determines how likely it is that all
requests will be served without delay. If the window is too small, or
traffic is too sparse, some requests will fall outside of it, and
block until the server can validate the cached response.