cache() integrates with Cloudflare’s Cache API to store and serve responses at the edge, and compress() shrinks response bodies using the Web-standard CompressionStream API. A third module, etag(), complements both by generating cache validators that let browsers skip downloads entirely when content hasn’t changed.
Cache middleware
cache() checks caches.default — the Cloudflare Cache API available in every Worker — before calling downstream handlers. On a cache hit, it returns the stored response immediately. On a miss, it lets the request proceed normally and stores the response in the cache for future requests.
The Cloudflare Cache API is scoped to the datacenter that handles each request. A response cached in Frankfurt is not automatically available in Singapore. For globally consistent caching, combine
cache() with a KV-backed strategy or use Cloudflare’s Cache Rules in your dashboard.CacheOptions reference
Caching GET responses
Cache-Control headers: if your handler already sets Cache-Control, cache() stores the response as-is without overriding it. Only responses with status codes in the 2xx–3xx range are stored.
Cache-Control passthrough
ETag middleware
etag() generates a weak ETag for each response body using a fast djb2 hash (no crypto overhead) and handles conditional requests via If-None-Match → 304 Not Modified. This means repeat visitors skip the download entirely when the content hasn’t changed.
EtagOptions
etag() patches res.json(), res.send(), and res.html() to intercept the response body before it’s sent. If the computed ETag matches the If-None-Match request header, it short-circuits to a 304 Not Modified with no body.
Compress middleware
compress() uses the Web-standard CompressionStream API to pipe response bodies through gzip or deflate compression. It checks the Accept-Encoding request header first, skips already-encoded responses (bodies with a Content-Encoding header), and skips responses below a configurable byte threshold.
CompressOptions
compress() sets Content-Encoding to the chosen algorithm, removes Content-Length (since the compressed size differs), and appends Accept-Encoding to the Vary header so caches store separate copies for compressed and uncompressed clients.
Combining cache + compress + etag
Layer all three middleware together for maximum performance. Order matters: compress the response first, then generate the ETag from the compressed bytes, then store the compressed + tagged response in the cache.etag()checks theIf-None-Matchheader against its computed ETag — sends304 Not Modifiedimmediately if unchanged.- The browser uses its local copy, paying zero bandwidth.
cache()checkscaches.default— cache hit, returns the stored compressed response immediately.etag()sets theETagheader on the outgoing response.- The browser receives the compressed response and caches the ETag for future requests.
cache()misses — callsnext()to run the route handler.- The route handler returns JSON.
compress()streams the body throughCompressionStream.etag()hashes the body, sets theETagheader.cache()stores the final compressed response incaches.default.- The browser receives the compressed, tagged response.