Clouldflare not respecting cache max-age

I have built a worker that does this more or less:

	cacheUrl.searchParams.delete('isJwtValid');
	cacheUrl.searchParams.append('isJwtValid', isJwtValid.toString());
	cacheUrl.searchParams.sort();
	
	const cacheKey = new Request(cacheUrl.toString(), request);
	const cache = caches.default;
	let response = await cache.match(cacheKey);

	if (!response) {
		response = await fetch(request);
		response = new Response(response.body, response);
		response.headers.append('Cache-Control', 's-maxage=' + cacheAgeSeconds);
		event.waitUntil(cache.put(cacheKey, response.clone()));	
	} else {
		response = new Response(response.body, response);
	}

Cache age is set to 30 days because my data only changes quarterly. When I request endpoints that I know have been requested in the last 24 hours I don’t always get a cache hit on the first request.

Is there something I am doing wrong in this script? How can I ensure items will remain cached? I am on a free account, but have no problems going to a paid account if that will resolve this issue.

max-age is respected - pedantically:

The max-age=N response directive indicates that the response remains fresh until N seconds after the response is generated.

Not all caches will guarantee that your response will be kept - it’s just that they’ll throw out the content after max-age since it’s gone stale and is no-longer fresh.

Cloudflare’s cache will evict assets that aren’t requested often enough at any time, and caching is also a per-PoP thing. There’s ~350 PoPs around the world so someone visiting your site from Tokyo might cache it there but that doesn’t mean the next request in London will hit a cached asset.

If they’re requested often enough, they’ll stay cached.

2 Likes

I figured as much.

If you would like something with more guarantee, you should use KV or Durable Objects. Unlike the Cache APIs though, these are not free, but would provide you more guarantees of things being kept for times that you want.

2 Likes

Fantastic, thank you.

@cherryjimbo looks at the KV docs, it doesn’t seem like I can just throw an entire response in there like I can with cache. Is this correct? Seems like I need to do a bit more work?

Correct, it’s not for Response objects directly. You’ll need to store a string, ReadableStream, or ArrayBuffer (if we’re talking about KV).

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.