Make Cloudflare CDN respect Cache-Control

I've been experimenting with Cloudflare CDN recently, and to be honest, I'm not super pleased. The interface seems to be more user-friendly than developer-friendly, and they don't support one of the most important features in many modern web applications - the stale-while-revalidate directive.

They claim to implement it, but it's misleading; it doesn't work well according to specifications and how other CDNs like Vercel Smart CDN, Fastly, and Cloudfront implement this. If you're interested in this topic, here's the original issue report created in 2018. It's now the end of 2024, and they still haven't implemented this most-requested feature by developers. All other major CDNs already support this, so it's a shame that Cloudflare doesn't. They've been moving the release date for 6 years, and now they've promised it's going to be available for beta-signed users in Q3 2024, which ends in a few days...

One of the features most requested by our customers is the asynchronous revalidation with stale-while-revalidate (SWR) cache directive, and we will be bringing this to you in the second half of 2024. This functionality will be available by design as part of our new CDN architecture that is being built using Rust with performance and memory safety at top of mind.

But this post is not about that issue! This post is about making Cloudflare respect the Cache-Control header and its directives. By default, Cloudflare bypasses files without extensions, so things like dynamic or SSR routes won't be cached. And even if you define Cache-Control, they will override it with their own settings - which is bad.

To fix it, you have to do a few things:

  1. Go to your Cloudflare dashboard and select the domain you want to configure.
  2. Go to the Caching tab.
  3. Click on the Configuration subpage.
  4. Scroll down to Browser Cache TTL and set it to Respect Existing Headers.
  5. Scroll down even further and disable Always Online™ if it's enabled.

Cloudflare Cache Rule

  1. Go back to the "Caching" tab and click on the Cache Rules subpage and create a new rule with the following format:
  • When incoming requests match…
  • All incoming requests
  • Then...
  • Cache eligibility: Eligible for cache
  • Edge TTL: Use cache-control header if present, bypass cache if not

Cloudflare Cache Rule

And that's it! Now Cloudflare will respect your Cache-Control headers and won't override them with their own settings. Just remember to configure your server/framework to always return Cache-Control for static files or other appropriate paths, and you're good to go!

P.S: If you're using Next.js and App Router, you won't be able to set a custom Cache-Control header... unless you provide your own custom server.


Published on September 24, 2024 3 min read