I'm using NextJS on my project. For every page requests it adds 's-maxage=31536000, stale-while-revalidate' cache-control rules in response. How are these 2 rules supposed to work together?
1 Answers
s-maxage
and stale-while-revalidate
are part of the cache-control
HTTP header standard that instruct caching of web objects.
As your question alludes, they are allowed to be comma separated to achieve your desired caching strategy.
Cache-Control: s-maxage=1, stale-while-revalidate=60
The first value (s-maxage
) is how long the object should be cached in seconds. It also "overrides max-age
or the Expires
header, but only for shared caches (e.g., proxies) and is ignored by private caches" - see HTTP expiration
The second value (stale-while-revalidate
), if supported, is how long after the s-maxage
expiration the object can be cached for until it needs to be requested from your site again.
Example
- Initial request - content is cached with the above
cache-control
directives - Request between 1-60 seconds after the initial request - Displays the cached content - revalidates in the background
- Request 60 or more seconds after the initial request - Cause the browser to request a new version of the content to serve.
Here is how to set caching headers in Next.js.
Here is a related post I made that highlights ISR process in Next.js.

- 5,663
- 18
- 31
-
2Note that `s-maxage` does *not* mean the same as `maxage` (see https://stackoverflow.com/q/39992837/733345); and the relevant spec would be 'HTTP', rather than 'HTML'. – Joe Aug 09 '21 at 09:36
-
Good catch Joe! Late night typo. I didn't explain how s-maxage overrides maxage for shared caches bc it's directly under max-age in the spec. But it's doesn't hurt to add it here for the tl;dr; – Sean W Aug 09 '21 at 16:11
-
1's-maxage=31536000, stale-while-revalidate' header is set by NextJS (SSG) out of the box for html requests. In your explanation you are saying that s-maxage header is for proxies only. Why do we need to cache html files on proxies? Why stale-while-revalidate doesn't have a value? – Dzianis Sudas Aug 11 '21 at 15:27
-
I didn't say it was only for proxies - that is the HTTP spec's explanation (see the spec I linked). Stale-while-revalidate doesn't have a value bc it's not being used. You'd cache a proxy so you don't have to hit your web servers on every request, it's standard to cache at the proxy level. https://www.imperva.com/learn/performance/cdn-caching/ – Sean W Aug 11 '21 at 15:36
-
2So for 's-maxage=31536000, stale-while-revalidate' does this mean stale-while-revalidate will be always ignored (because it doesn't have a value) and the html file requested will be cached on proxy (CDN) for 1 year? – Dzianis Sudas Aug 11 '21 at 15:46
-
1If you are using a server that respects the s-maxage header, it will request (not guaranteed) to be cached for 1 year in your case. The proxy server can also set it's own cache eviction rules (common example aws cloudfront cache invalidation). Yes, stale-while-revalidate is essentially off. – Sean W Aug 11 '21 at 18:21
-
In this example, isn't `stale-while-revalidate` a client-side header used alongside the server-side `s-maxage`? Does Next.js support server-side stale-while-revalidate in an API route via a header? – Stephen Marsh May 04 '23 at 22:07