Skip to content

Limitations

This page lists the scenarios where Workers Caching does not apply, followed by notes on how it relates to other caches you may already be using.

Unsupported scenarios

HTTP methods

Only GET and HEAD requests are cached. POST, PUT, PATCH, DELETE, and other methods always invoke your Worker.

GET and HEAD for the same URL share a single cache entry. A HEAD request that arrives on a cold cache is converted to a GET internally so the cache is populated with the full asset. Refer to Cache keys.

If you need to cache responses to non-idempotent requests, do so explicitly in your Worker — for example, by hashing the request body into a synthetic URL and making an internal GET subrequest.

WebSocket upgrades

WebSocket upgrade requests (GET with Upgrade: websocket) bypass the cache and always invoke your Worker. WebSocket sessions are stateful by definition and are not a meaningful unit of caching.

Custom RPC methods

Only fetch() invocations on a WorkerEntrypoint go through Workers Caching. Custom RPC methods like ctx.exports.Backend.getUser(id) bypass the cache and always run the callee, regardless of the entrypoint's cache.enabled setting.

To cache a piece of work that is currently exposed as an RPC method, refactor it to a fetch handler on its own entrypoint and call it with fetch().

Status codes that are never cached

Workers Caching never stores the following responses, even with explicit Cache-Control directives:

  • 520526 (Cloudflare failsafe responses) are treated as transient errors and always re-run the Worker.
  • 206 Partial Content returned by your Worker is not stored — Workers Caching expects your Worker to return the full 200 response and does the range slicing itself. Refer to Range requests for the supported pattern.

Other invocation types

Workers Caching only applies to HTTP requests handled by a fetch handler on a Worker entrypoint. The following invocation types always run without cache involvement:

Purge by host

There is no "purge by host" mode. The cache belongs to the Worker, not to a domain — the host is not part of the cache key, so purging by host would not map onto anything the cache stores. Use purge by tag, purge by path prefix, or purgeEverything instead.

Cache pre-warming

There is no API to pre-populate the cache with responses generated at build time. A response is only cached once it has been served at least once. If you need pre-rendered content available to the first requester, use Static Assets.

Limits

Response size

Response size limits are the same as Cloudflare's zone cache. For per-plan limits, refer to Cacheable size limits.

Cache-Tag limits

Limits on the number, length, and character set of Cache-Tag values are the same as Cloudflare's zone cache. Refer to Cache tag limits for the full list.

Purge rate limits

ctx.cache.purge() uses the same rate-limiting system as the zone purge API. Refer to Availability and limits for the rates that apply to your account.

Relationship to other caches

Zone-level cache configuration

Workers Caching is your Worker's cache, not your zone's cache. It uses your Worker itself as the configuration surface, so there is no separate layer of rules or settings to configure alongside it. None of the following applies to Workers Caching:

Zone-level featureEquivalent in Workers Caching
Cache Rules and Cache Response RulesSet Cache-Control headers in your Worker, or branch on the request and return different headers per path.
Cache key customization in Cache RulesWorkers Caching has its own key composition; see Cache keys. Shape the key by shaping the request (for example, by rewriting the URL or setting ctx.props in a gateway Worker).
Zone-level cache level settings (bypass / standard / aggressive / ignore query string)Cache-Control headers on the response express the same intent at a per-request level.
The zone's default cached-file-extensions listWorkers Caching caches any response whose headers say it is cacheable, regardless of file extension.
Custom tiered cache topologiesWorkers Caching uses a generic tiered cache topology by default. Because a Worker can execute anywhere, a fixed custom topology does not apply — future integrations with Smart Placement may tailor tiering further.
Rulesets that modify request or response before cacheTransform the request or response in your Worker's code before returning it.

To influence your Worker's cache, change your Worker. Cache-Control headers, ctx.props, service binding composition, and ctx.cache.purge() cover the configuration surface.

Cache API (caches.default)

The Cache API is a separate programmatic cache store. It is independent of Workers Caching — operations on one do not affect the other, and ctx.cache.purge() is what invalidates Workers-Caching entries.

For new Workers, prefer Workers Caching. The Cache API, by design, is a lower-level primitive:

  • It does not read through — responses are only cached when your Worker explicitly calls put(), and every request still executes your Worker on the way in.
  • It does not collapse concurrent requests for the same resource. A burst of traffic to a fresh URL invokes your Worker once per request.
  • It does not participate in tiered caching.

Workers Caching provides all three automatically. The Cache API remains useful when you need fine-grained programmatic control.

fetch() subrequest caching

Workers Caching is a server-side cache in front of your Worker. It is a separate cache from the one that sits in front of outgoing fetch() subrequests your Worker makes to its own origins. The two operate independently: a fetch() subrequest hit saves a trip to your origin, while a Workers Caching hit saves your Worker from running at all.

The cf properties on a Request behave differently across the two:

cf propertyOn outgoing fetch() to your originOn ctx.exports.<Entrypoint>.fetch()
cf.cacheKeySupportedSupported — see Custom cache keys
cf.cacheControlSupportedSupported — see Override Cache-Control from the calling Worker
cf.cacheTtlSupportedNot supported — set the TTL by returning Cache-Control: max-age=N (or s-maxage=N) from the callee, or by overriding it with cf.cacheControl from the caller
cf.cacheEverythingSupportedNot supported — Workers Caching decides cacheability from the response's Cache-Control; there is no override to force-cache an otherwise uncacheable response

Coming soon

The following surfaces are in development:

  • Dashboard UI for enabling caching without Wrangler.
  • Cache Analytics in Workers Observability.