
A CDN delivering your images and CSS is a good start. A CDN delivering your full HTML pages is a different level of performance. When a visitor’s browser request never reaches your origin server at all, your PHP stack, your database, and your object cache are completely out of the picture. For high-traffic pages, that means near-instant response times from a data center close to the visitor, with your origin sitting quietly under far less load.
The challenge is that WordPress was not designed with this pattern in mind. It sets cookies, varies output for logged-in users, and generates cart-specific HTML. A naive cache-everything rule will cause real problems. This guide walks you through getting full-page edge caching right: the rules, the bypasses, the purge strategy, and the pitfalls to watch for.
Why Full-Page Edge Caching Is Worth the Effort
Standard CDN configurations cache files that have obvious, static URLs: .jpg, .css, .woff2. HTML pages are excluded by default because CDNs assume they are dynamic. Cloudflare, for example, will pass WordPress page requests straight to your origin unless you explicitly tell it otherwise.
When you configure the edge to serve cached HTML, several things improve at once. Time to first byte drops because the response comes from a nearby edge node. Your origin handles far fewer PHP processes, which reduces memory pressure. Traffic spikes become less dangerous because most requests never touch your server. And Core Web Vitals metrics, particularly LCP (target of 2.5 seconds or under), benefit directly from a faster initial document response.
The Basic Mechanism: Cache Rules and Cache-Control Headers
Cloudflare decides whether to cache a response based on two things: the Cache-Control header your origin sends, and any explicit Cache Rules you configure in the Cloudflare dashboard.
WordPress core sends Cache-Control: no-cache, must-revalidate, max-age=0 for most pages. That tells Cloudflare not to cache them, which is why pass-through is the default. To override this, you create a Cache Rule in Cloudflare that matches your desired URLs and sets the edge cache TTL to a value you choose, ignoring the origin header. A TTL of one hour to four hours is a reasonable starting point for evergreen content.
You can also address this from the origin side. Plugins and server configurations can send a Cache-Control: public, max-age=3600, s-maxage=3600 header on cacheable pages. The s-maxage directive specifically targets shared caches like CDNs while leaving the browser cache unaffected. LiteSpeed Cache, for example, can be configured to send appropriate headers for full-page caching when the server is LiteSpeed or OpenLiteSpeed.
Cookie Bypass Rules: The Most Important Part
WordPress stores login state and cart state in cookies. If a cached page is served to a logged-in user, they will see the wrong content. If a WooCommerce cart page is cached, one shopper’s cart may appear for a different visitor. These are serious bugs, not minor inconveniences.
The correct approach is to bypass the edge cache whenever certain cookies are present. In Cloudflare Cache Rules, you can add a condition that checks the request cookie header. A reliable bypass list includes:
wordpress_logged_in_*(set when a user is logged in)wordpress_sec_*(authentication nonces)woocommerce_cart_hashandwoocommerce_items_in_cartwp-postpass_*(password-protected posts)- Any custom session cookies your theme or membership plugin sets
When any of these cookies are present, the request goes straight to your origin. Anonymous visitors browsing your public pages get the cached edge response. The rule is: cache the anonymous experience, always bypass for authenticated or session-carrying users.
On the query string side, you should also decide how to handle parameters like UTM tags. Cloudflare can be configured to ignore specific query parameters when computing the cache key, so /page/?utm_source=email and /page/ serve the same cached object. Be careful with parameters that genuinely affect page output, such as pagination or search terms.
Purging the Cache When Content Changes
Edge caching creates a consistency problem. You publish a post or update a page, but Cloudflare still serves the stale cached version until the TTL expires. For a site with a four-hour TTL, that means visitors could see outdated content for hours after a change.
The solution is cache purging triggered by WordPress events. Several approaches exist:
- Plugin-based purge hooks: Plugins that integrate with Cloudflare’s API can purge specific URLs whenever a post is saved, updated, or a comment is approved. Cloudflare’s own official plugin provides this. LiteSpeed Cache handles purging for the LiteSpeed server-level cache and can be extended.
- Purge by tag: Cloudflare’s Cache Tags feature (available on higher-tier plans) lets you tag cached responses with identifiers like a post ID, then purge all responses sharing that tag in a single API call. This is the most precise option for large sites.
- Purge everything: A blunt option useful after major changes like theme updates or plugin upgrades. Straightforward but temporarily increases origin load as the cache warms up again.
Using wp-cli, you can script purge actions as part of a deployment workflow:
wp post list --post_status=publish --format=ids | xargs -I{} wp cf-cache purge --post_id={}The exact commands depend on which Cloudflare integration plugin you use, but the principle is the same: tie purge calls to WordPress lifecycle hooks so the cache stays fresh automatically.
Handling Dynamic Elements on Cached Pages
Full-page caching does not mean every element on the page must be static. You can cache the HTML shell of a page at the edge and fetch dynamic fragments separately. Two patterns handle this well:
Edge-cached page with JavaScript-driven dynamic sections. The cached HTML loads instantly. JavaScript then makes an authenticated XHR or fetch call to a separate endpoint to populate things like a cart count, user greeting, or personalized recommendations. The user sees content fast, and dynamic data loads in shortly after. This pattern works well for WooCommerce stores where the product pages are identical for all anonymous visitors.
Fragment caching at the origin. For sections that vary but do not require an API call, WordPress can use object caching (Redis or Memcached) to serve pre-computed HTML fragments from memory. This is faster than a full database query even when the edge cache is bypassed.
Layer Your Caching Strategy
Edge caching works best as one layer in a coordinated stack, not as a replacement for everything else. A well-structured setup looks like this, from outermost to innermost:
- Edge (Cloudflare): Full-page HTML cache for anonymous users, static asset caching, WAF, and DDoS protection. Origin IP stays unpublished to prevent attackers from bypassing the edge entirely.
- Server-level page cache: LiteSpeed Cache stores full-page HTML on disk or in memory at the origin. If a request bypasses Cloudflare or arrives after a purge, the server cache responds without running PHP.
- Object cache (Redis): Persistent object caching via a drop-in stores database query results and transients in memory. PHP runs, but the database does not.
- PHP with OPcache: PHP 8.3 with OPcache enabled keeps compiled bytecode in memory. Even uncached requests run as fast as possible.
Each layer catches requests the outer layer does not. The edge handles the bulk of traffic. The server cache handles post-purge warmup and logged-in edge cases. Redis handles authenticated user sessions. OPcache makes the residual PHP work efficient.
Measuring Whether It Is Actually Working
After configuring full-page edge caching, verify it is behaving correctly before assuming success.
- Check the
CF-Cache-Statusresponse header. A value ofHITconfirms the response came from Cloudflare’s cache.MISSmeans it went to origin (which is expected on the first request after a purge).BYPASSmeans a bypass rule fired, which is correct for logged-in users. - Test from a browser with no WordPress cookies set (an incognito window you have never used to log in).
- Use PageSpeed Insights or Lighthouse to check LCP, INP, and CLS against their thresholds. Field data from the Chrome User Experience Report reflects real visitors and is the more meaningful signal; lab data is useful for fast iteration during development.
- Confirm that logged-in admin users see live content, not cached pages, and that WooCommerce cart pages are never cached.
Takeaway
Full-page edge caching is one of the highest-leverage performance improvements available to a WordPress site. The setup work is primarily in defining your bypass rules carefully, wiring up purge hooks so content stays fresh, and deciding how to handle dynamic elements. Get those three things right and the majority of your page requests will be served from the edge, fast and cheap, with your origin reserved for the work only it can do.