Fix Cache-Control Headers on Cloudflare

Last updated: April 2026

Cloudflare caches based on origin Cache-Control headers and its own edge TTL. Configure both for predictable caching behaviour.

Audit your Cloudflare cache headers live โ†’

Cache Rules โ€” recommended (2024+)

Dashboard โ†’ Your domain โ†’ Caching โ†’ Cache Rules โ†’ Create rule.

# Static assets โ€” cache at edge 1 year
When: File extension matches js, css, woff2, png, jpg, webp
Then: Edge TTL = 1 year, Browser TTL = 1 year, Cache status = Cache

# API โ€” bypass cache
When: URI path starts with /api/
Then: Cache status = Bypass

Transform Rules โ€” modify Cache-Control header

Dashboard โ†’ Rules โ†’ Transform Rules โ†’ Modify Response Header.

# Static assets
Set Cache-Control: public, max-age=31536000, immutable

# API responses
Set Cache-Control: no-store

# HTML pages
Set Cache-Control: no-cache

Cloudflare Worker โ€” full control

export default {
  async fetch(request, env) {
    const response = await fetch(request);
    const url = new URL(request.url);
    const headers = new Headers(response.headers);

    if (url.pathname.startsWith('/api/')) {
      headers.set('Cache-Control', 'no-store');
    } else if (/\.(js|css|woff2|png|jpg)$/.test(url.pathname)) {
      headers.set('Cache-Control', 'public, max-age=31536000, immutable');
    } else {
      headers.set('Cache-Control', 'no-cache');
    }

    return new Response(response.body, { status: response.status, headers });
  }
};

stale-while-revalidate on Cloudflare

Cache-Control: public, max-age=60, stale-while-revalidate=300

Verify cache headers

curl -sI https://yoursite.com/app.js | grep -iE "cache-control|cf-cache-status|age"
📚 HttpFixer Blog โ€” fix guides, explainers, and references โ†’