Note: Cloudflare doesn't Cache HTML by Default

Share

If you're using Cloudflare, you may run into an issue where you have a high Time to First Byte (TTFB) rating when using webpage performance measurement tools like Google's Pagespeed Insights or when looking at Google's Chrome real usage data CRUX reports.

One possible reason for this high TTFB may be that the HTML isn't being cached, which means that every time anyone accesses your website it uses Cloudflare as the reverse proxy which adds latency to every page access.

Cloudflare doesn't cache HTML by default, even if you set the appropriate cache-control headers. This means your web server may be configured properly, returning the correct cache-control HTTP header with maxage or s-maxage, but Cloudflare simply ignores that because it doesn't cache everything by default.

Additionally, Cloudflare doesn't use MIME types to tell the content of a file to tell whether it should cache the file. It just uses the file extension of the URL. This means that, oddly, if you have a HTML file with a URL that ends in .jpg, that will be cached because Cloudflare assumes it's a JPG image so it uses the default JPG image caching rules.

Cloudflare only caches based on file extension and not by MIME type. The Cloudflare CDN does not cache HTML or JSON by default. Additionally, by default Cloudflare caches a website's robots.txt.

https://developers.cloudflare.com/cache/concepts/default-cache-behavior/ (accessed 2025-04-25)

How to Tell If You Have This Problem

Open the inspector on Chrome and switch to the Network tab, then access your webpage. Click on the first entry that will appear, for the URL accessed not for the images, to display the HTTP headers. If you have the header CF-Cache-Status: DYNAMIC, that means the URL isn't eligible for caching according to the current rules.

By the way, CF-Cache-Status: MISS means that it's eligible, but it wasn't in the cache at the time, and CF-Cache-Status: HIT means it was already in cache. After you fix the issue, you'll naturally need to access the same URL two times to see the HIT appear.

How to Fix

Before you try to fix this, it's important to understand why this is disabled by default in first place.

If a HTML webpage uses a CSS stylesheet or Javascript file, it will have its URL in the HTML code. These files are cached by default, and that's already enough to create all sorts of caching problems.

For example, let's say you have /cool-effect.js that adds a cool effect to a .navbar HTML element. One day you update your website, removing the .navbar HTML element and changing /cool-effect.js to add a cool effect to the .footer element instead. Because the Javascript is cached, users will get the old Javascript with the new HTML, which is going to break the website's behavior. There are many caching techniques we can use to fix this, the most simple being just using a unique URL for each version of the Javascript (e.g. /cool-effect.js?version=2025-04-25).

If we cache the HTML, we can run into the same problem but in reverse. Now our HTML may be old but our JS and CSS may be new. In particular, if we completely chance our classes, but serve the old CSS, the whole page may look unstyled because the CSS selectors won't match anything anymore.

Only cache the HTML if you have designed your website to work with caching, and, in particular, took the appropriate measures to ensure that updates don't break the website. Note that if your website is simple enough, you can simply log into Cloudflare and choose the option to clear the entire cache every time you update. That should work, too.

To make Cloudflare cache HTML: go to Rules -> Cache Rules on the sidebar, and add a rule to cache everything. Currently, there is a template for this so it takes 2 clicks to create this rule.

Use a filter instead of on "all requests" if you want to limit the HTML cache to certain URL's.

Important: it's a good idea to make the "cache everything" rule the first rule on your rules list. That's because the last rule matched is the one used, so to override the "cache everything" rule you must create a "Bypass Cache" rule below it, not above.

Written by Noel Santos.

About the Author

I'm a self-taught Brazilian programmer graduated in IT from a FATEC. In a world of increasingly complex and essential computers, I decided to use my technical expertise in hardware, desktop applications, and web technologies to create an informative resource to make PC's easier to understand.

View Comments