Cloudflare Cache Confusion

3 hours ago 1
October 26, 2025

I’ve used cloud func­tions of many fla­vors over the years, from AWS Lambda to Google Cloud Func­tions to Val Town. Cloud­flare Workers is the latest and greatest, a great refine­ment of the genre, and it’s the canvas for most of my pro­gram­ming these days.

So here’s a Cloud­flare Workers thing.

Workers grant you pro­gram­matic access to Cloud­flare’s caching infrastructure, so it seems like you ought to be able to run a tight little globally-cached web server, mer­rily spit­ting out files stored in R2, like so:

export default { async fetch(request, env, ctx) { const cache = caches.default; const cachedResponse = await cache.match(request); if (cachedResponse) { return cachedResponse; } // Not in the cache, so, proceed to R2 const url = new URL(request.url); const key = url.pathname.slice(1); // to make R2 key const object = await env.BUCKET.get(key); if (object === null) { // return 404 page } const freshResponse = new Response(object.body, { status: 200, headers: { "Content-Type": object.httpMetadata.contentType || "text/html", "Cache-Control": "public, max-age=604800", "Festina-Lente": "true" }, }); // Cache it!! ctx.waitUntil(cache.put(request, freshResponse.clone())); return freshResponse; }, };

Seems like it … but, alas, it’s not that simple, for two reasons:

  1. The cache available to Workers is per-datacenter, rather than global like Cloudflare’s “traditional” cache. This means that the first request to any given datacenter won’t be cached, which is annoying, but not a showstopper.

Here is the showstopper:

  1. The cache available to Workers can't be controlled by the Cache API. So, to purge files from the Workers cache (after, e.g., uploading fresh versions to R2), you'd have to write your own invalidation layer.

Which maybe sounds fun to some people — freaks! — but, for me, the attrac­tion here was simplicity.

Here I will be precise. There is one way to con­trol the Workers cache using the Cache API. You can simply

{ purge_everything: true }

but that feels pretty gross, right? Again, the attrac­tion here was some­thing light and elegant, and PURGING EVERYTHING when­ever you change a comma in a blog post is not elegant.

But Robin (you might say, as I said to myself), why don’t you just use a worker as a tra­di­tional “origin”, run­ning its responses through the same caching logic that Cloud­flare applies to any other origin, e.g. the old Linux box whirring next to your minifridge? Another disappointment. When you con­nect a domain to a worker, Cloud­flare passes requests straight through, as Chris Krycho discovered.

For anyone else strug­gling with this — maybe you found this post via search — here is my main clar­i­fying takeaway: the Workers Cache API should be con­sid­ered a totally sep­a­rate system from the Cache API and indeed the global, “tra­di­tional” Cloud­flare cache. It is not, in fact, totally sep­a­rate, but that assump­tion sets you on the right track. It did for me, at least.

P.S. The cir­cuitous com­plexity of this page in Cloud­flare’s docs might illus­trate the depth of the con­fu­sion here 😵‍💫

P.P.S. Type it this many times in a row, and you realize “worker” is a weird-looking, weird-sounding word. Wrrr-krrr?!

To the blog home page
Read Entire Article