GraphQL Cache Demo

See how Cloudflare Workers can cache POST requests using the Cache API

How It Works

1️⃣

Hash the Query
The Worker creates a unique cache key by hashing the GraphQL query + variables

2️⃣

Check Cache
Uses the Cache API to look for a stored response matching that key

3️⃣

Store or Return
On MISS: fetch from origin, store in cache. On HIT: return instantly

Send a Query

💡 Click the same query twice to see the cache HIT

Response

Send a query to see results

Request History

No requests yet

GET vs POST: See the Difference

Click each button multiple times to see how Cloudflare handles caching differently.

GET Native Edge Cache

Cloudflare caches GET requests automatically when Cache-Control headers are set. Check the cf-cache-status header!

Click to test...
POST Never Cached by Default

POST requests always hit origin. Notice the response time never improves - there's no cf-cache-status header.

Click to test...

This is why GraphQL (which typically uses POST) needs the Worker Cache API pattern shown above.

The Worker Code

This is the actual code running on Cloudflare Workers to cache POST requests:

// Hash function to create unique cache keys
async function sha256(message) {
  const msgBuffer = new TextEncoder().encode(message);
  const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer);
  return [...new Uint8Array(hashBuffer)]
    .map((b) => b.toString(16).padStart(2, "0")).join("");
}

if (request.method.toUpperCase() === "POST") {
  // Clone request so we can read body AND forward to origin
  const body = await request.clone().text();
  
  // Hash the request body to use as part of the cache key
  const hash = await sha256(body);
  
  // Build cache URL by appending hash to the original URL
  const cacheUrl = new URL(request.url);
  cacheUrl.pathname = "/posts" + cacheUrl.pathname + hash;
  
  // Convert to GET request (Cache API requirement)
  const cacheKey = new Request(cacheUrl.toString(), {
    headers: request.headers,
    method: "GET",
  });

  const cache = caches.default;
  let response = await cache.match(cacheKey);

  if (!response) {
    // Cache MISS - fetch from origin, then store
    response = await fetch(request);
    ctx.waitUntil(cache.put(cacheKey, response.clone()));
  }
  return response;
}

From developers.cloudflare.com/workers/examples/cache-post-request