How the Cache works
Since Workers was built atop Cloudflare’s network, since its early days, it was designed to allow developers to interact directly with the Cloudflare cache. The cache can provide ephemeral, colo-local storage, as a convenient way to frequently access static or dynamic content.
Since Cloudflare’s Workers can run before, and after the cache, a Worker can also be utilized to modify assets once they are returned from the cache, to sign or personalize responses, while reducing load on an origin, or latency to the end user by serving assets from a nearby location.
Interacting with the Cloudflare Cache
Conceptually, there are two ways to interact with Cloudflare’s Cache using a Worker:
Call to in a Workers script. Requests proxied through Cloudflare are cached even without Workers according to a zone’s default or configured behavior (e.g. static assets like files ending in .jpg are cached by default). Workers can further customize this behavior by:
Customizing cache behavior of any asset by setting headers such as
Cache-Controlon the response passed to
Caching responses generated by the Worker itself through
Edge vs. browser caching
The browser cache is controlled through the
Cache-Control header sent in the response to the eyeball (the response passed or promised to
event.respondWith()). Workers can customize browser cache behavior by setting this header on the response.
What should I use: the Cache API or fetch for caching objects on Cloudflare?
For requests where Workers are behaving as middleware (i.e. they are sending a subrequest via
fetch) it is recommended to use fetch. This is because pre existing settings are in place that optimize caching while preventing unintended dynamic caching. For projects where there is no backend (i.e. the entire project is on Workers as in ) the Cache API is the only option to customize caching.
In the context of Workers a provided by the runtime communicates with the Cloudflare cache. First,
fetch checks to see if the URL matches a different zone. If it does, it reads through that zone’s cache (or Worker!). Otherwise, it reads through its own zone’s cache, even if the URL is for a non-Cloudflare site. Cache settings on
fetch automatically apply caching rules based on your Cloudflare settings.
fetch does not allow you to modify or inspect objects before they reach the cache, but does allow you to modify how it will cache.
When a response fills the cache, the response header contains
CF-Cache-Status: HIT. You can tell an object is attempting to cache if one sees the
CF-Cache-Status at all.
The Cache API can be thought of as an ephemeral key-value store, whereby the
Request object (or more specifically, the request URL) is the key, and the
Response is the value.
There are two types of cache namespaces available to the Cloudflare Cache:
caches.default– You can access the default cache (the same cache shared with
fetchrequests) by accessing
caches.default. This is useful when needing to override content that is already cached, after receiving the response.
- New namespaces – You can access a namespaced cache (separate from the cache shared with
let cache = await caches.open(CACHE_NAME). This can be useful when writing new content to the cache, for example after running a more compute heavy operation such as parsing HTML or running a computation, to store them locally in the colo and readily access them on the following request, rather having to rerun the same operation. Note that is an async function, unlike
When to use the Cache API:
- When you need to read from cache without calling fetch. (i.e. send me the response from
slow.com/resourceif and only if it’s already a HIT on cache using
- Explicitly store a response in the cache using
caches.default.put(..)and explicitly delete
caches.default.delete(..). For example, say your origin is returning
max-age:0and you can’t figure out how to change that header at your origin. You can explicitly tell Cloudflare to cache this response by setting
cache-control: max-age=1000on the response passed into