Blog Cache API responses at the edge with Workers

Cache API responses at the edge with Workers

2 min read

Cache API responses at the edge with Workers
TL;DR A Cloudflare Worker can sit in front of an API, check the edge cache, and only call the origin on a miss. Cache successful responses with a sensible TTL, serve hits from the edge, and you cut latency and origin load without touching the origin.

If you call a third-party API that is slow, rate-limited, or costs per request, hitting it on every page view is wasteful. A Cloudflare Worker in front of it, caching responses at the edge, fixes that with a small amount of code. Here is the pattern.

The shape of it

The Worker intercepts the request, checks the edge cache, and only calls the origin API when there is no cached copy. On a miss, it fetches, stores the response, and returns it. On a hit, it serves from the edge and never touches the origin.

export default {
  async fetch(request, env, ctx) {
    const cache = caches.default;
    const cacheKey = new Request(request.url, request);

    let response = await cache.match(cacheKey);
    if (response) return response; // edge hit

    response = await fetch("https://api.example.com/data");
    response = new Response(response.body, response);
    response.headers.set("Cache-Control", "public, max-age=300");

    ctx.waitUntil(cache.put(cacheKey, response.clone()));
    return response;
  },
};

What to cache, and what not to

Cache stable, shareable data: public listings, reference data, anything the same for every user. Set a TTL that matches how fresh it needs to be.

Do not cache authenticated or per-user responses, rapidly changing data, or errors. Pass those straight through so you never serve one user another's data or a stale error.

Keeping it fresh

Two simple strategies cover most needs.

  • Short TTL for data that changes often. A five-minute cache still removes almost all the repeated calls.
  • Versioned keys for data that changes on release. Put a version in the URL, and a new version naturally misses the old cached entry.

For manual control, the Worker can delete specific cache entries when you know data has changed.

Why it is worth it

You get most of a CDN's benefit for an API that was never designed to be cached, without changing the origin. Latency drops because responses come from near the user, and your origin stops carrying repeated identical requests. A few lines at the edge do the work.

FAQ

Why cache an API at the edge instead of the origin?

The edge is close to users and absorbs repeated requests before they reach your origin. Caching there cuts round-trip latency and shields a slow or rate-limited origin from load, without changing the origin itself.

What should I not cache?

Per-user or authenticated responses, anything that changes constantly, and error responses. Cache stable, shareable data with a TTL that matches how fresh it needs to be, and pass everything else straight through.

How do I bust the cache when data changes?

Use a short TTL for data that changes often, or key the cache on a version in the URL so a new version misses the old entry. For manual invalidation, you can delete specific cache keys from the Worker.