Why does the Cache API cache automatically add or change the `maxage` in the `cache-control` header?

I wrote the following code
const cache = cache.default;
const cacheKey = generateCacheKey(request);
const cacheData = await cache.match(cacheKey);

if (cacheData != null) {
return cacheData;
}

const beresp = await fetch("https://example.com", { headers: { "X-TEST": req.headers.get("X-TEST") }});
const data = await beresp.json();
const responseBody = JSON.stringify(data);

const res = new Response(responseBody, {
status: beresp.status,
headers: { "content-type": "application/json" }
});

res.headers.set("cache-control", "public, s-maxage=60");
res.headers.set("vary", "X-TEST");

ctx.waitUntil(cache.put(cacheKey, res.clone()));

return res;
const cache = cache.default;
const cacheKey = generateCacheKey(request);
const cacheData = await cache.match(cacheKey);

if (cacheData != null) {
return cacheData;
}

const beresp = await fetch("https://example.com", { headers: { "X-TEST": req.headers.get("X-TEST") }});
const data = await beresp.json();
const responseBody = JSON.stringify(data);

const res = new Response(responseBody, {
status: beresp.status,
headers: { "content-type": "application/json" }
});

res.headers.set("cache-control", "public, s-maxage=60");
res.headers.set("vary", "X-TEST");

ctx.waitUntil(cache.put(cacheKey, res.clone()));

return res;
The response from Cloudflare Workers at this time is shown in the first image. Because this is the first request, it has not hit the cache yet. However, the second one is the response header when the cache is hit. Contrary to my intention, max-age=14400 is given to cache-control. Also, when maxage=60 is used instead of s-maxage, maxage=14400 is overwritten in the same way. I would like a reason for this behavior and documentation. Also, I have specified s-maxage=60, so I expect a HIT to be returned for 1 minute, but for what reason would the request be routed to origin?
4 Replies
Unsmart
Unsmartβ€’10mo ago
I do believe that is this: https://developers.cloudflare.com/cache/how-to/edge-browser-cache-ttl/#browser-cache-ttl You can change the default value here: https://dash.cloudflare.com/?to=/:account/:zone/caching/configuration I would set it to "Respect Existing Headers"
JJ
JJβ€’10mo ago
@Unsmart | Tech debt Thank you very much. This is the first time I have seen this admin page. It helped me a lot.
Unsmart
Unsmartβ€’10mo ago
No problem πŸ™‚ I'm honestly not sure the rationale behind defaulting browser cache like that as it has definitely bitten people in here before and I think respecting existing headers really should be the default but yeah thats what it is for now πŸ˜…
JJ
JJβ€’10mo ago
I think they are trying to make it faster by adding a default, but 4 hours is too long to be the default. πŸ˜… Whenever an engineer forget to revving the content and use this functionality, accidents will be sure to happen.