LiteSpeed Cloudflare APO LCP tuning works best when the two layers are given distinct jobs rather than left to overlap: LiteSpeed Cache handles server-side page and object caching close to the origin, while Cloudflare’s Automatic Platform Optimization pushes cached HTML to Cloudflare’s edge network globally. Running both without dividing responsibilities causes the exact caching conflicts and stale-content bugs we hit first-hand while building out this site’s own speed stack.
On this page
Why run both layers instead of just one
LiteSpeed Cloudflare APO LCP optimization is not redundant the way running two identical caching plugins would be, because the two systems solve different distance problems. LiteSpeed Cache eliminates the expensive part of a WordPress page load — PHP execution and database queries — by serving a fully rendered page straight from the web server. Cloudflare APO then takes that already-cheap page and serves it from whichever of Cloudflare’s edge locations is physically closest to the visitor, cutting the network round-trip time that server-side caching alone cannot touch. Together they attack both halves of time-to-first-byte: the compute side and the distance side of the same problem.
Dividing responsibility between the two caches
The rule that has worked for us running this exact combination is straightforward: LiteSpeed Cache owns page cache, object cache, and image optimization; Cloudflare APO owns edge distribution of the already-cached HTML and does not get asked to also minify or restructure the page. Letting both layers try to rewrite or minify the same HTML is where the LiteSpeed Cloudflare APO LCP setup starts fighting itself — one layer’s minification can interfere with the other’s cache key generation, producing cache misses that look like a caching failure but are actually a caching disagreement between two systems each doing their job correctly in isolation.
What actually moved our LCP number
On this site specifically, the largest LCP improvement did not come from either cache alone — it came from disabling one specific LiteSpeed feature. We deliberately did not enable LSCache’s own lazy-load feature, because in our testing it applied lazy-loading to the hero image along with everything else below the fold, which delays exactly the element LCP measures. The combination that worked was LiteSpeed serving the cached page fast at the origin, Cloudflare APO distributing that page globally, and the hero image explicitly marked `loading=”eager” fetchpriority=”high”` so neither caching layer could defer it. That single exclusion mattered more to our LiteSpeed Cloudflare APO LCP number than any general-purpose cache setting we tuned afterward.
The caching conflicts we hit and how we fixed them
We hit two concrete problems running LiteSpeed and Cloudflare APO together on this site, both documented in our own operational history. First, a stale 404 response got cached at the Cloudflare edge for a full hour after the underlying WordPress error was already fixed, because LiteSpeed’s own cache-ttl configuration includes a default 404 cache window and Cloudflare APO respected it at the edge too — meaning a transient error can outlive its cause by an hour across two cache layers instead of one. Second, a week-long browser-level HTML cache from an unrelated `.htaccess` `mod_expires` rule made menu and content changes invisible to returning visitors even after both LiteSpeed and Cloudflare caches were correctly purged, because the browser never revalidated at all. Neither problem was solved by purging one cache — both required identifying which of the three cache layers, browser, edge, or origin, was actually holding the stale copy in that specific instance.
The specific settings we run today
Enabled on LiteSpeed Cache: page cache, object cache, browser cache, CSS and HTML minification, and emoji-script removal. Deliberately disabled: CSS/JS combine and LSCache’s own lazy-load, both of which caused more problems than they solved during testing on this site. On Cloudflare APO: HTML edge caching is on, and we set HTML cache-control headers to `no-cache, must-revalidate, max-age=0` at the browser level specifically so a returning visitor always revalidates against the edge cache rather than holding a stale local copy for days at a time.
Cache headers versus browser behavior
It is worth being explicit that disabling the browser’s own long-lived cache does not slow the site down the way it sounds like it should. LiteSpeed still serves the page instantly from its own server-side cache, and Cloudflare APO still serves it instantly from the edge; the browser revalidation this forces is a fast conditional request, not a full page rebuild. The tradeoff is a small number of extra round trips in exchange for guaranteeing that a menu change, a corrected typo, or a fixed error page reaches every visitor immediately instead of sitting invisible in someone’s browser cache for up to a week, which is exactly the failure mode that first forced us to make this change.
How to verify the stack is actually working
Checking response headers is the fastest way to confirm a LiteSpeed Cloudflare APO LCP setup is functioning as intended: `x-litespeed-cache: hit` confirms the origin-level cache is serving the page, and Cloudflare’s `cf-cache-status: HIT` header confirms the edge is also serving from cache rather than re-fetching from origin on every request. If either header is missing or shows a miss on a page that should be cached, the fix is almost always in cache-key configuration or a plugin generating dynamic content that both caching layers correctly refuse to cache — not a reason to disable caching altogether.
Join the discussion
Add useful context, ask a focused question or share relevant experience. Comments are moderated to protect readers from spam and promotional links.

Leave a thoughtful comment