Skip to content
Website Speed

Cloudflare Caching for WordPress: Defaults, HTML, Purging

Cloudflare caches your static files by default but not your pages. How to read its cache header, cache HTML safely and keep it in step with your WordPress cache.

A line chart printed on paper, trending upwards
8 sections · 8 min read
In this article · 8 sections

You moved your domain to Cloudflare, the records turned orange, and the site still works. Good. But when you run a speed test, the server response time looks much the same as before, and you are not sure whether Cloudflare is caching anything at all. Meanwhile a plugin keeps offering to “connect to Cloudflare” and a forum post insists you need a rule to cache everything.

This guide to Cloudflare caching for WordPress is written for site owners rather than network engineers. The short answer to the first worry: Cloudflare is almost certainly caching your images and scripts already, and almost certainly not your pages. Whether to change that is the main decision, and it needs more care than forum posts suggest. If you want the background on what a CDN is in the first place, our explainer on how a CDN works and whether you need one covers it.

What Cloudflare caches the moment you switch it on

With your DNS records proxied through Cloudflare, it starts caching static files straight away. It decides what counts as static mainly by file extension: images, stylesheets, JavaScript, fonts, PDFs and similar downloadable files. Those are stored at Cloudflare’s data centres and served from the one nearest each visitor.

Your HTML pages are not cached by default. Every request for a page still goes through Cloudflare to your hosting server, which builds the page, or serves it from your WordPress page cache, and sends it back. That is why the server response time in a speed test often barely changes after switching Cloudflare on. The images and scripts arrive from nearby, but the page itself still comes from your origin.

This default is deliberately cautious. Cloudflare cannot know which of your pages are personal: carts, account pages, logged-in views. Treating HTML as uncacheable avoids serving one visitor’s page to another.

Reading the cf-cache-status header

Cloudflare adds a header named cf-cache-status to responses it handles. Open your browser’s developer tools, go to the Network tab, reload the page and click any request to see it. The common values:

Value What it means
HIT Served from Cloudflare’s cache. Your server was not asked.
MISS Cacheable, but not stored yet at this location. Fetched from your server and, normally, stored for next time.
EXPIRED A stored copy had run out of time, so a fresh one was fetched.
BYPASS A rule or a header from your server told Cloudflare not to use the cache for this request.
DYNAMIC Not considered cacheable at all. This is what HTML pages show by default.
REVALIDATED A stored copy was checked with your server and confirmed still valid.

A healthy default setup shows HIT on images, CSS and JS after the first load, and DYNAMIC on the page itself. Note that each Cloudflare location keeps its own cache. A visitor in another country may get a MISS on files you already see as HIT. That is one reason sites can feel different overseas, a subject covered in our post on why a site is slow for overseas visitors.

How long files stay at the edge and in browsers

Two separate lifetimes are at play. One is how long Cloudflare keeps a file at its data centres. The other is how long visitors’ browsers keep it. Both are influenced by the cache headers your server sends and by Cloudflare’s own settings.

The browser side is where conflicts often appear. Cloudflare has a browser cache setting that can either respect what your server sends or apply its own lifetime. If you set long lifetimes on your server, or through a WordPress plugin, and the browser receives something different, check that setting. Pick one place to control browser lifetimes and leave the other alone. Our explanation of browser cache lifetimes sets out what sensible lifetimes look like for each file type.

Caching HTML on Cloudflare, with care

Caching your pages at Cloudflare’s edge can cut server response time sharply, especially for visitors far from your hosting, because the page never has to travel from your origin. It is also the change most likely to cause real harm on a WordPress site if done carelessly.

The ways to do it

  • A cache rule in your Cloudflare dashboard that marks HTML as eligible for caching, usually with conditions that skip certain paths and cookies. Older guides describe the same idea using page rules and a “cache everything” setting.
  • Cloudflare’s Automatic Platform Optimization (APO) for WordPress, an option built for this job. It works alongside the official Cloudflare WordPress plugin and is designed to clear cached pages when content changes. How it is offered and exactly what it bypasses can change, so read Cloudflare’s current documentation before relying on it for a shop.
  • A caching plugin’s Cloudflare integration. Some WordPress caching plugins can manage Cloudflare purging, and a few help set up edge caching. What each one does varies, so read its documentation.

What must be kept out

Whichever route you take, the edge cache must not store or serve:

  • Anything under /wp-admin/ and the login page.
  • Requests from logged-in users, identified by WordPress’s wordpress_logged_in_ cookie.
  • On a store, the cart, checkout and account pages, and any request carrying WooCommerce’s cart or session cookies. Our list of WooCommerce pages and cookies to exclude applies at Cloudflare just as it does in a plugin.
  • Pages for members, bookings, quotes or anything else personal.
  • Preview links and REST API requests.

The difficulty is that a simple rule can only skip what it can see. If your rule can match on cookies, you can bypass logged-in users and shoppers. If it cannot, edge-caching HTML on a site with logins or a cart is risky, and a purpose-built option is the safer choice. On a brochure site where only you log in, a path-based rule that skips the admin and login pages is often enough.

Lifetimes for cached HTML

Keep edge lifetimes for HTML modest unless you have reliable automatic purging. A page cached for days at Cloudflare will keep showing the old version after you edit it, wherever your visitors are, until it expires or you purge it.

Purging the Cloudflare cache

Cloudflare lets you clear a single address, a list of addresses, or the whole cache from the dashboard. Clearing a single address is usually enough for a changed image or one edited page. Clearing everything means every location fetches every file again from your server, which is harmless but causes a brief burst of extra load and slower first views worldwide.

The better arrangement is automatic purging: when you update a post in WordPress, the relevant addresses are cleared at Cloudflare too. The official Cloudflare plugin and several caching plugins can do this once connected with an API token. Without it, you have two caches to clear by hand after every change, and it is easy to forget the second.

When you purge manually, go from the inside out: your WordPress page cache first, then any host cache, then Cloudflare. Clear Cloudflare first and it may immediately fetch and store the old page again from the layer beneath.

Where Cloudflare and your page cache conflict

  • Two HTML caches with different lifetimes. If Cloudflare caches HTML for a day and your plugin’s for a few hours, a purge in WordPress does nothing for visitors until Cloudflare is cleared too. Connect the purging, or let only one of them cache HTML.
  • Cloudflare caching a page your plugin marked as private. A rule that forces caching can override the no-cache headers WordPress and WooCommerce send on personal pages. Rules must explicitly bypass those paths and cookies.
  • Overlapping script optimisation. Cloudflare has a feature called Rocket Loader that changes how JavaScript loads. If your WordPress plugin is also deferring or delaying scripts, the two can clash and break menus, sliders or forms. Use one tool for script loading, not both.
  • Image optimisation in two places. If both Cloudflare and a WordPress plugin resize or convert images, results get confusing. Choose one.
  • Browser lifetimes set twice. As above, choose whether your server or Cloudflare decides.

Setting up Cloudflare caching for WordPress, in order

  1. Get the WordPress page cache working properly first, with its exclusions tested.
  2. Proxy the site through Cloudflare and check that static files show HIT on a second load.
  3. Decide who controls browser cache lifetimes, and set that one place.
  4. Connect your caching plugin or the Cloudflare plugin so content updates purge Cloudflare automatically.
  5. Only then consider caching HTML at the edge, with bypasses for logged-in users, the admin and any store pages.
  6. Test logged out and logged in, in two browsers, including a form submission and, on a store, a full test order.
  7. Check cf-cache-status on pages, cart and account to confirm each behaves as intended.

Edge caching is one piece of a fast site, and our site speed guide covers the rest. For where Cloudflare sits relative to browser, page, object and opcode caches, see the overview of website caching layers.

Frequently asked questions

Why does Cloudflare show DYNAMIC for my pages?

DYNAMIC means Cloudflare did not consider the response cacheable, which is the default for HTML pages. It is normal and safe. Your pages are still delivered through Cloudflare, but they come from your hosting server each time. Only a cache rule or an add-on built for WordPress changes that.

Do I still need a WordPress caching plugin with Cloudflare?

In most cases yes. By default Cloudflare caches static files but not pages, so your server still builds or serves every page. A page cache on the server keeps that fast. Even with HTML cached at the edge, the server cache helps on every miss and for visitors who bypass the edge cache.

Will caching HTML at Cloudflare break my contact form?

It can, if the cached page carries a security token that expires before the page is refreshed, or if form submissions are caught by a cache rule. Keep edge lifetimes for HTML modest, make sure form submissions are not cached, and test the form logged out after any change to cache rules.

How do I check whether Cloudflare is caching my images?

Open the page, then open the browser’s developer tools, choose the Network tab and reload. Click an image request and look for the cf-cache-status header. HIT means Cloudflare served it from its cache. MISS on the first load followed by HIT on the next is the expected pattern.

When Cloudflare and the WordPress cache are working against each other, the fix is usually to decide which layer does which job. That review is part of the caching setup in our website speed service, and it includes testing carts, forms and logins before and after.

Next in this series: Caching Plugin Broke My Site: Safe Rollback and Fixes

Is Your Website Working Properly?

Get a free website health check from WebMaintor. We'll review your website's speed, security, forms, and technical health — and tell you exactly what needs attention.

No obligation. No automated reports. A real review by our team.