Problem with cache API in worker.
I'm having problems with the cache API in my worker.
High-level setup: I have a single website, let's call it mcguirer.com, with some pages served by a NextJS Pages app (let's say it's at mcguirer.pages.dev), which retrieves page content from a headless CMS.
The mcguirer.com URLs that are served by the pages app, are routed to a worker (mcguirer-worker) that changes the URLs from, for example, https://mcguirer.com/blog/april2025 to https://mcguirer.pages.dev/blog/april2025. The worker then does the fetch() and returns the response. Any URL that is not a worker route for that worker is routed directly to the origin server. My problem is with getting the pages served by the worker to be cached. I've tried multiple versions of worker code using the cache API, both a the match() and put() idiom and the fetch() idiom, and none of them seem to do that right thing; - https://developers.cloudflare.com/workers/runtime-apis/cache/ - https://developers.cloudflare.com/workers/examples/cache-using-fetch/ In both cases, the cache seems to be ignored. If I start with an empty cache, load a page that's routed through the worker, make a change to the page content in the CMS, clear my browser cache, and reload the page, I get the new version of the page. I would expect the old version of the page to be served from cache for the cache TTL of four hours. I also a cache rule with a trigger condition of http.host eq "mcguirer.com" and an action of "Eligible for cache" and "Ignore cache-control header and use this TTL - 4 hours". However, I'm getting the same worker behavior regardless of whether I have the Cache Rule enabled or not. BTW, yes, I tried searching for previous messages about this issue. I found a few, but the proposed solutions didn't work. I'm going to continue searching back through the history here.
High-level setup: I have a single website, let's call it mcguirer.com, with some pages served by a NextJS Pages app (let's say it's at mcguirer.pages.dev), which retrieves page content from a headless CMS.
The mcguirer.com URLs that are served by the pages app, are routed to a worker (mcguirer-worker) that changes the URLs from, for example, https://mcguirer.com/blog/april2025 to https://mcguirer.pages.dev/blog/april2025. The worker then does the fetch() and returns the response. Any URL that is not a worker route for that worker is routed directly to the origin server. My problem is with getting the pages served by the worker to be cached. I've tried multiple versions of worker code using the cache API, both a the match() and put() idiom and the fetch() idiom, and none of them seem to do that right thing; - https://developers.cloudflare.com/workers/runtime-apis/cache/ - https://developers.cloudflare.com/workers/examples/cache-using-fetch/ In both cases, the cache seems to be ignored. If I start with an empty cache, load a page that's routed through the worker, make a change to the page content in the CMS, clear my browser cache, and reload the page, I get the new version of the page. I would expect the old version of the page to be served from cache for the cache TTL of four hours. I also a cache rule with a trigger condition of http.host eq "mcguirer.com" and an action of "Eligible for cache" and "Ignore cache-control header and use this TTL - 4 hours". However, I'm getting the same worker behavior regardless of whether I have the Cache Rule enabled or not. BTW, yes, I tried searching for previous messages about this issue. I found a few, but the proposed solutions didn't work. I'm going to continue searching back through the history here.
Cloudflare Docs
Cache using fetch
Determine how to cache a resource by setting TTLs, custom cache keys, and cache headers in a fetch request.
4 Replies
Derp, I see there's a separate workers-help channel, should I move this question there? Is there a way to that's easier than editing it here and copy-and-pasting?
Discord provides no easy way to do so, not too big of a deal tho
mcguirer.com doesn't look like a real website, not sure if I understand the rest of your setup though
mcguirer.com is supposed to be a pages custom domain which fetches a worker (or calls, via service bindings?), which fetches something else?
You could add logging on the .match and see if there's any matches at all
@Chaika, thank you for your reply.
True, mcguirer.com is not a real site. I was just using that name to anonymize my post - kinda like www.example.com. As for the DNS entries... In my company's official DNS, which is NOT Cloudflare, I have a CNAME record for mcguirer.com that references mcguirer.com.cdn.cloudflare.net. Then in my CF DNS, I have an A record for mcguirer.com with an IP addr of the site that serves the pages that aren't served by the NextJS pages app. So all requests for mcguirer.com go to Cloudflare. The request for URLs that are serviced by the pages app are routed to the worker. Any URLs that shouldn't go to the pages app, won't go to the worker and instead fall through to the non-cloudflare site at the IP address in the CF DNS A rec. All that has been working perfectly fine for over a year. The only issue I'm having is that the pages served by the pages app don't seem to be cached at all.
True, mcguirer.com is not a real site. I was just using that name to anonymize my post - kinda like www.example.com. As for the DNS entries... In my company's official DNS, which is NOT Cloudflare, I have a CNAME record for mcguirer.com that references mcguirer.com.cdn.cloudflare.net. Then in my CF DNS, I have an A record for mcguirer.com with an IP addr of the site that serves the pages that aren't served by the NextJS pages app. So all requests for mcguirer.com go to Cloudflare. The request for URLs that are serviced by the pages app are routed to the worker. Any URLs that shouldn't go to the pages app, won't go to the worker and instead fall through to the non-cloudflare site at the IP address in the CF DNS A rec. All that has been working perfectly fine for over a year. The only issue I'm having is that the pages served by the pages app don't seem to be cached at all.
In my company's official DNS, which is NOT Cloudflare, I have a CNAME record for mcguirer.com that references mcguirer.com.cdn.cloudflare.net. Then in my CF DNS, I have an A record for mcguirer.com with an IP addr of the site that serves the pages that aren't served by the NextJS pages app. So all requests for mcguirer.com go to Cloudflare. The request for URLs that are serviced by the pages app are routed to the worker.You're describing a partial cname dns setup. You have an A record for that origin. You have a worker route on that, handling traffic for specific urls/etc and then fetching through to Cloudflare Pages. You can't cache the result of the worker itself, only within the worker. You could add logging for cache.match, or you return the result of cache.match directly or use fetch caching, look at the response headers and the cf-cache-status for cache info. If it's missing, cache wasn't attempted (or is using cache.match, you didn't match)