How does stale-while-revalidate interact with s-maxage in Cache-Control header?
Asked Answered
H

3

10

Just want to know around the header that I have specified for my SSR pages: public, s-maxage=3600, stale-while-revalidate=59.

Please note that my stale-while-revalidate value is 59 seconds which is way less than s-maxage value which is 1 hour. I want to know that when stale-while-revalidate value is smaller than s-maxage, what happens exactly? Is the stale-while-revalidate header ignored?

Huntingdonshire answered 16/6, 2022 at 8:38 Comment(0)
S
10

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:

  1. The page is considered fresh for 3600 seconds (max-age=3600);
  2. 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.

Silicosis answered 21/6, 2022 at 22:15 Comment(4)
once a stale-while-invalidate fires, and gets a "fresh" page.. does the process start all over again? Meaning, that "new" page now has 3600 to be served from cache before a "new" page is generated?Discontinue
@jamesemanon Yes, that's correct. The new page gets cached for another 3600s.Silicosis
The answer is largely based on what would happen if max-age (and not s-maxage) was used. With s-maxage this timeline won't happen. Please see my answer.Thirtyone
@DanilaVershinin Thanks for the correction. I'll update my answer to reflect that.Silicosis
T
1

Chiming in for performance researches out there. s-maxage "nulls" the effect of stale-while-revalidate in shared proxies. In other words, there is no background validation and serving stale content by shared cache.

So while they do both work (s-maxage applies to shared and stale-while-revalidate will apply at browser), the expectation that you have stale while revalidate setup in shared cache is incorrect. There are no background updates done by shared cache.

From RFC 9111 HTTP Caching:

The s-maxage directive incorporates the semantics of the proxy‑revalidate response directive (Section 5.2.2.8) for a shared cache. A shared cache MUST NOT reuse a stale response with s-maxage to satisfy another request until it has been successfully validated by the origin, as defined by Section 4.3.

To answer question as is, no, these cache lifetimes will not even overlap because they are applied to different caches.

Thirtyone answered 11/12, 2023 at 18:41 Comment(1)
The section of the RFC you've copied is referring to proxy-revalidate which is not the same as stale-while-revalidate. I don't think this applies and that it is valid for s-maxage and stale-while-revalidate to be used concurrently.Floranceflore
D
1

The directive stale-while-revalidate can apply to both private (browser) 1 and public (CDN, proxy) 2 3 caches, if they support it. It starts to take effect once the object becomes stale in that cache for the first x seconds of staleness.

The Fastly docs show this nicely:

Fastly cache diagram

In your example, a browser would immediately consider the response stale, but reuse a cached response in the first 59 seconds, while revalidating it in the background. After 59 seconds, the revalidation would block the response as normal.

A proxy would first use the s-maxage and consider the response fresh for 1 hour, delivering it without revalidating. After that, it would use stale-while-revalidate (between 1:00:00 and 1:00:59) and deliver the stale response while revalidating in the background. Starting 1:01:00 after the last revalidation, the response is considered expired and will not be delivered without first revalidating.


1. MDN: Cache-Control Browser Support
2. Fastly Docs
3. Cloudfront Docs

Downtown answered 15/7 at 9:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.