I’ve setup a page rule for my domain to use origin cache control and I’m serving Cache-Control headers that look like this: Cache-Control: public, max-age=60, stale-while-revalidate=600, stale-if-error=86400
But the content does not seem to be getting cached at all, cloudflare sends the CF-Cache-Status: DYNAMIC header for all requests. Is 60 seconds too short or is there something else I need to do to make cloudflare respect my cache headers?
Thanks for the response. I’ve tried 120s now, same problem. I think 2 minute cache is pretty reasonable with a stale-while-revalidate of 10minutes, is there anything else I can try to debug this?
Tried setting a cache level, no effect. Page rule now reads Cache Level: Standard, Origin Cache Control: On and the matching pattern is *mydomain.com/*
That appears to be an experimental directive at this point and I wouldnt be surprised if it is neither supported by Cloudflare nor possibly applicable to Cloudflare’s edge cache at all.
Same behaviour, after 60s I get CF-Cache-Status: EXPIRED and my server is hit (synchronously via same request it looks like by the response time increase)
indicates that caches MAY serve the response in which it appears after it becomes stale, up to the indicated number of seconds since the resource expired.
you’re confusing the different caches - cloudflare cache vs browser cache. max-age and cache control headers are to control browser level cache and not cloudflare’s cache
to confirm max-age = 60 second browser level cache is working check response header for the file/page in browser developer tools/network tab
s-max-age value controls shared proxies like cloudflare’s cache
max-age=seconds
The “max-age” response directive indicates that the response is to be considered stale after its age is greater than the specified number of seconds. Age is defined as the time in seconds since the asset was served from the origin server. The seconds argument is an unquoted integer.
s-maxage=seconds
The “s-maxage” response directive indicates that, in shared caches, the maximum age specified by this directive overrides the maximum age specified by either the max-age directive or the Expires header field. The s-maxage directive also implies the semantics of the proxy-revalidate response directive.
AFAIK s-maxage is just an override for max-age if you want different behaviour in browser and shared caches. I’m only speaking about the cloudflare cache here not any browser caches.
The cache headers I’m serving has the expected behaviour in Nginx using proxy_cache when setting proxy_cache_background_update on; FYI. There I get stale content on a miss after 60s (with fresh content on a subsequent request) and it will not hit my server synchronously until the cache has been stale for 10min
You might need to contact cloudflare tech support and ask them under which circumstances other than Always Online, where stale-while-revalidate is not respected by cloudflare cache.
When present in an HTTP response, the stale-while-revalidate Cache-Control extension indicates that caches MAY serve the response in which it appears after it becomes stale. It doesn’t mean we can’t go to the origin to get a copy and serve it instead. But if there are other waiting requests for the same content we will serve the stale response i believe.
I do like RFCs for their precision in language. Note the use of the term MAY. For the fist subsequent request for an asset at a POP we will go to the origin to revalidate. If there are subsequent requests for that asset before we have revalidated it we will not make additional trips to the origin or wait on the response from the initial requery, but will instead serve the stale asset to those requests.
So to demonstrate it working you would need multiple requests for the same asset in the same POP for an object which took long enough to revalidate that between the time we went off to the origin to validate the first request in the stale-while-revalidate window and the time we retrieved the new object those additional requests could be served the stale version.
SWR is an optional extension to Cache-Control; that’s what’s meant by the “MAY” in the RFC. You can be a compliant HTTP proxy while completely ignoring SWR (as, indeed, Cloudflare does).
This guide should be updated to say that instead of confusing users by implying it is supported.