In short:
Let’s say s-maxage is one day and max-age is one hour. The proxy cache will keep a resource for a day, but after a few hours the Age header will be more than one hour. The browser sees the resource is older than one hour and won’t cache it locally. How to cache it locally in the browser regardless?
I'm trying to combine Cache-Control: max-age and s-maxage with sensible values.
But setting s-maxage > max-age doesn't seem to make sense.
Eventually the browser will always revalidate resources and will skip local browser cache, because resources received from proxy cache will immediately be stale (Age > max-age).
Goals:
- Reduce load on origin: set long TTL at edge cache (
s-maxage), this can be purged when necessary. - Speed up browser session: set small cache on browser (
max-age).
Problem:
A resource stays in proxy cache for a long time (s-maxage), while its Age increases (time since fetch from origin).
Eventually the Age of the resource in cache will be larger than max-age.
When that happens the browser will revalidate every time it needs a resource, since the resource is stale on every request.
For example: Cache-Control: max-age=60, s-maxage=86400.
The browser should keep a resource for 60 seconds. The proxy cache keeps a resource for a day.
t=0
browser: need resource
proxy cache: fetch resource from origin
-> cache returns fresh resource with Age: 0 / Cache-Control: "max-age=60, s-max-age=86400"
t=30
browser: locally cached resource is still fresh: Age (0+30) < max-age (60)
t=70
browser: local cache is stale: Age (0+70) > max-age (60) -> revalidate
proxy cache: cached resource is still fresh: Age (70) < s-maxage (86400)
-> cache returns resource with Age: 70, Cache-Control: "max-age=60, s-maxage=86400"
The cache returned a resource with an Age (70) that is larger than max-age (60).
From now on every time the browser wants the resource it will be stale locally and needs revalidation.
t=75
browser: local cache is stale: Age (70+5) > max-age (60) -> revalidate
proxy cache: cached resource is still fresh: Age (75) < s-maxage (86400)
-> cache returns resource with Age: 75 / Cache-Control: "max-age=60, s-max-age=86400"
This means that if a resource is in proxy cache for longer than max-age the browser will always revalidate.
The max-age value is only useful for max-age seconds after getting a fresh resource from origin.
- Is this expected behavior?
- How can I adjust this such that the browser will always cache a resource for 60s after requesting it, even if that received resource has been in proxy cache for a long time? (Or is this bad practice?)
s-maxage.max-ageands-maxagedoesn't seem to be useful in practice, unlessmax-age = 0(always revalidate) ormax-age > s-maxage(longer local cache).s-maxage. (For example, Cloudfront has various settings,Minimum TTLetc.)TTLwould help with purging, but I'm not sure how a customTTLsetting would help with the original problem, i.e.max-age: 60andTTL: 86400— after 60 seconds the browser will always revalidate as theAgeof the resource in cache still increases.TTLands-maxagehave essentially the same behaviour (exceptTTLwon't propagate to other caches). I guess the only way to do this is if I have control over theAge/Dateheaders and adjust those to0/now?