---
title: "WordPress cache warming: preload your page cache and your CDN — warmup.rocks"
description: "WordPress has two caches to warm: the page cache on your server and the CDN edge cache. How WP Rocket, LiteSpeed and FlyingPress preload works, what it misses, and how to keep WooCommerce fast."
canonical: https://warmup.rocks/blog/wordpress-cache-warming
---

WordPress

# WordPress cache warming: preload your page cache _and_ your CDN

July 2026 · 9 min read · [← All posts](https://warmup.rocks/blog/)

An uncached WordPress page is expensive: PHP boots, the theme renders, plugins run their hooks, and MySQL answers a few dozen queries. On typical shared hosting that's 500 ms to several seconds of server time — for every single uncached request. That's why every serious WordPress setup caches. And why the pages that _aren't_ in cache when a visitor arrives are the ones that hurt.

The catch most guides skip: WordPress sites have **two separate caches** that go cold independently — and the popular "preload" features only warm one of them.

## The two caches (and who warms what)

| Layer | Where it lives | Warmed by |
| --- | --- | --- |
| Page cache | Your server (WP Rocket, LiteSpeed, W3TC, FlyingPress, host-level cache) | Plugin preload / crawler |
| CDN edge cache | 300+ data centers worldwide (Cloudflare, bunny.net, …) | Nothing, by default |

The **page cache** stores rendered HTML on your server so PHP and MySQL are skipped. The **CDN edge cache** stores that HTML in data centers close to your visitors, so the request never reaches your server at all. A visitor served from the edge gets the page in tens of milliseconds; a visitor who misses both caches waits for the full PHP render plus the round trip across the globe.

## What plugin preload actually does

Most caching plugins ship a preload feature, and they're genuinely useful:

-   **WP Rocket** reads your sitemap and requests every URL after the cache lifespan expires or after you clear the cache, rebuilding the page cache in the background.
-   **LiteSpeed Cache** has a server-side crawler that walks the sitemap on a schedule — including separate passes for mobile and per-cookie cache variations.
-   **FlyingPress** and **W3 Total Cache** do sitemap-based preloading in the same spirit.

All of these run _on or next to your server_. They warm the origin page cache — and that's all. The request that fills the page cache in your hosting data center does **nothing** for the Cloudflare colo in Sydney, São Paulo or Singapore. If your CDN caches HTML, each of its hundreds of edge locations still starts cold and stays cold until a real visitor from that region takes the slow first hit.

**Rule of thumb:** plugin preload fixes the _server-side_ cold cache. It cannot fix the _edge-side_ cold cache, because warming an edge cache requires requests that physically enter the CDN network at each location. One server can't do that — this is the same [geography problem we covered for Cloudflare](https://warmup.rocks/blog/cloudflare-cache-warming).

## Step 1: get the page cache right

1.  **Pick one page cache.** Two caching plugins fight each other. If your host caches at the server level (most managed WordPress hosts do), you often don't need a plugin page cache at all.
2.  **Enable its preload/crawler** and point it at your sitemap. Set the preload to re-run after the cache lifespan expires.
3.  **Don't purge everything on every edit.** Configure the plugin to purge only the changed post plus affected archives — a full purge on every save means your whole site runs cold several times a day.
4.  **Add an object cache** (Redis or Memcached) if you run WooCommerce, memberships or anything with logged-in users. It doesn't cache pages, but it makes the uncacheable requests bearable.

## Step 2: cache HTML at the edge

By default, Cloudflare and most CDNs cache your images, CSS and JS — but _not_ your HTML. Your TTFB is still your server's TTFB. To fix that on Cloudflare, either:

-   Use **APO for WordPress** (Cloudflare's paid add-on that caches HTML at the edge and purges on publish via the plugin), or
-   Create a **Cache Rule**: eligible for cache when the request doesn't carry a WordPress session cookie:
    
    ```
    (http.host eq "example.com"
     and not http.cookie contains "wordpress_logged_in"
     and not http.cookie contains "woocommerce_cart_hash"
     and not starts_with(http.request.uri.path, "/wp-admin"))
    ```
    
    …with "Eligible for cache" and an edge TTL of a few hours to a few days. Purge on publish with a plugin like Cloudflare's own or Super Page Cache.

Not sure whether your HTML is actually cached at the edge? Paste a URL into our free [cache checker](https://warmup.rocks/cache-checker) — if it reports `DYNAMIC`, your HTML isn't cached and everything below won't help until it is.

## Step 3: warm the edge

Once HTML is cacheable at the edge, you have the second cold-cache problem: hundreds of edge locations, each with its own copy, each starting empty after every purge and TTL expiry. Organic traffic keeps your top pages warm in your top markets — and leaves the long tail cold everywhere else. The math is unforgiving: a site with 500 pages on a CDN with 300 locations has **150,000 cache slots** to fill.

This is the part a warming service handles: [warmup.rocks](https://warmup.rocks/) reads the same sitemap your caching plugin uses and requests every page through proxies in 40+ countries on a schedule — one request per edge location, so each colo stores its own copy. After every run you see the [hit ratio](https://warmup.rocks/blog/cache-hit-ratio) per URL and per location, so you can verify the edge is actually staying warm.

## WooCommerce: what you can and can't warm

WooCommerce adds dynamic state — carts, sessions, checkout — and that changes the rules:

-   **Cache product, category and content pages.** They're the same for every anonymous visitor and they're where organic traffic lands. Warm these aggressively.
-   **Never cache cart, checkout or account pages.** Every page cache plugin excludes them by default; make sure your CDN rule does too (the `woocommerce_cart_hash` cookie exclusion above handles it).
-   **Watch the session cookie trap:** some setups start a WooCommerce session on the first page view, which sets a cookie and makes _every_ page uncacheable for that visitor. Fix the plugin/theme that triggers the session before warming anything.
-   **Use AJAX fragments for the mini-cart** (WooCommerce does this out of the box) so a cached product page can still show a live cart count.

The payoff is biggest exactly here: a store's long tail of hundreds of product pages is where cold caches cost real revenue — a shopper who waits 3 seconds for a cold product page bounces before your upsell ever renders.

## A sane setup, summarized

1.  One page cache (plugin or host-level) with sitemap preload enabled → server cache warm.
2.  Object cache (Redis) for the dynamic leftovers.
3.  CDN caches HTML via APO or a Cache Rule, purge-on-publish wired up.
4.  [warmup.rocks](https://warmup.rocks/) warms every edge location from the same sitemap on a schedule → edge cache warm, verified per colo.
5.  Check the result with the [cache checker](https://warmup.rocks/cache-checker): every location should report `HIT`.
