How to cache Magento HTML at the Cloudflare edge without caching checkout
Turn on Magento edge caching with OCM Labs Cloudflare: bypass paths, vary handling, query strings, and how to verify with curl and health checks.

What stops most people from running a Magento edge cache is the fear of caching the wrong page: a cart with someone else's items, an account page served to a stranger. The way out is to stop asking Cloudflare to guess. Magento already decides which pages are safe, and the module makes Cloudflare follow that decision.
This is post 2 in the series. It assumes post 1 is done and the recommended cache rules are applied. Without the "Cache storefront HTML" rule Cloudflare never caches HTML, whatever headers the origin sends.
How the module reuses Magento's full page cache decision
Magento's full page cache stores a page only when every block on it is cacheable, the request is a GET, no bypass condition applies and the response does not set a context cookie. OCM Labs Cloudflare, free and open source, reuses that decision. A page the full page cache would store is marked for the edge. Anything else goes out as private, no-store.
The mechanism is a plugin on Magento's page cache kernel. When the kernel is about to save a response, the plugin adds two markers: an internal edge TTL header and a Cache-Tag header built from the page's cache tags. The kernel saves headers with the body, so the markers survive on full page cache hits, and a page served from Magento's own cache carries the same edge headers as a fresh render. Full detail is on the edge caching docs page.
The headers Cloudflare sees
On a cacheable response, with edge caching on:
Cache-Control: public, max-age=0, s-maxage=3600
CDN-Cache-Control: public, max-age=0, s-maxage=3600
Cache-Tag: cat_p_12, cat_c_3, store, website, cms_b_5s-maxage is the edge TTL. max-age=0 is for the browser: returning visitors revalidate with Cloudflare every time, so a purge reaches them too. Cache-Tag carries the lowercased Magento cache tags, which is what tag purges use. Tags are capped to fit Cloudflare's header limits; the "Cache-Tag header size" health check counts pages that had to drop any.
Every other response gets Cache-Control: private, no-store: bypass paths, non-GET requests, responses that set the X-Magento-Vary cookie, and every storefront response while edge caching is off.
On responses it marks cacheable, the module also strips the Set-Cookie headers Magento's kernel and Varnish VCL drop (PHPSESSID, form_key, private_content_version, mage-cache-sessid, mage-messages), whether Laminas-set or native PHP, so a cached copy never hands the first visitor's session to everyone after them.
Configure the Edge Cache group
Go to Stores > Configuration > OCMLabs > Cloudflare > Edge Cache. The group is website scoped, so switch the scope selector to the website before editing.
Enable Edge Caching of HTML. Default No, and while it is No every storefront response carries private, no-store, so a zone with a stray "Cache Everything" rule cannot cache HTML by accident. Set it to Yes. Edge TTL (seconds). Blank inherits Magento's full page cache TTL from system/full_page_cache/ttl. Fill it in only if the edge should hold pages for a different time than Magento does. Bypass Paths. One path prefix per line. Requests under these paths are never marked cacheable, and the "Bypass protected paths" cache rule is built from the same list. The default list:
/checkout
/customer
/sales
/wishlist
/paypal
/rest
/graphql
{admin}
/downloadable
/newsletter/subscriber
/review/product/post
/catalogsearch/advanced/result
/contact{admin} expands to your real admin frontName. The check runs twice, when Magento decides whether to cache and again when the response is sent, so a path added after a page is already in Magento's full page cache is still honored.
Vary Handling. Magento sets the X-Magento-Vary cookie when a visitor's context differs from the default: another store view, another currency, a customer group with its own prices, or a logged-in session. Those pages must never be served to a default-context visitor, or the other way round. Bypass is the default and works on every plan: the "Bypass on vary cookie" rule sends requests carrying the cookie to the origin, where Magento's own full page cache serves them, and any response that sets the cookie is marked no-store. Default-context visitors, the majority on most stores, get the edge. Cache key is Enterprise only: the cookie value joins Cloudflare's cache key, so each store view, currency and customer group is cached as its own variant. On a non-Enterprise zone the module falls back to Bypass and says so in the rules preview and the health checks. Cache Query Strings. Default Yes: Cloudflare caches each distinct URL including its query string, which is right for layered navigation and pagination. Set it to No and every request with a query string goes to the origin through a "Bypass query strings" rule the module adds. Static and media paths are excluded, so versioned asset URLs stay cached either way.
Save, then re-apply the cache rules so the zone matches, with bin/magento ocmlabs:cloudflare:rules:apply --dry-run first to see the diff.
Add your payment and shipping callback paths
The default list does not know about your extensions. Payment gateways post notifications to a path of their own, and shipping modules expose address lookup and rate endpoints. Add each to Bypass Paths as a prefix, then purge everything, because Cloudflare keeps whatever it cached before the change until the TTL runs out:
bin/magento ocmlabs:cloudflare:purge --allStore switch URLs (___store= and ___from_store=) always bypass the edge. You do not need to add them.
Luma and Hyva
Cached HTML is safe for both themes. Both render the page anonymously and load private content in the browser afterwards, Luma through Knockout customer-data sections and Hyva through its Alpine.js private-content loader. The module only lets Cloudflare cache a default-context anonymous render, which is what Magento's own full page cache stores. No Hyva compatibility module is needed. What breaks the themes is Cloudflare features that rewrite the page; the health checks flag each one.
| ROCKET LOADER (BREAKS REQUIREJS AND ALPINE.JS) | Turn off in Speed > Optimization > Content Optimization |
|---|---|
| AUTO MINIFY ON OLDER ZONES (SAME) | Turn off; Magento minifies its own assets |
| EMAIL OBFUSCATION (REWRITES HTML, INJECTS A SCRIPT) | Turn off in Scrape Shield |
| ALWAYS ONLINE (SERVES STALE PRICES AND STOCK) | Turn off in Caching > Configuration |
| BROWSER CACHE TTL (OVERRIDES MAX-AGE=0, SO PURGES MISS RETURNING VISITORS) | Set to Respect Existing Headers |
Verify with curl and the live probes
Request a category page twice:
curl -sI https://www.example.com/some-category.html | grep -iE "cf-cache-status|cache-control|cache-tag"cf-cache-status: HIT from the second request onward means the edge is serving the page. You will not see Cache-Tag once the page is cached; Cloudflare strips it from the response it sends to visitors. Then request a customer page the same way and expect BYPASS or DYNAMIC, never HIT.
Next, open System > Cloudflare > Dashboard > Health and click Run checks now, or run:
bin/magento ocmlabs:cloudflare:healthThree probes fetch real storefront pages through Cloudflare and read cf-cache-status:
- Edge caches a storefront page: a category page twice,
HITexpected on the second. - Edge bypasses customer and checkout pages: the login page,
BYPASSorDYNAMICexpected. - Edge handles the vary cookie: a request carrying
X-Magento-Vary, which the edge must not serve from cache.
Probe URLs come from the website's own catalog. The command exits 1 on any failure, so it can gate a deploy.
When cf-cache-status is DYNAMIC everywhere
Cloudflare did not consider the page cacheable. Work down this list in order:
- Edge caching is off (the default). Check Enable Edge Caching of HTML at website scope.
- No cache rule. Apply the recommended rules.
- The module is disabled. Check Enable Cloudflare Integration at default scope.
- Varnish with stock VCL, which rewrites
Cache-Controltono-cache. Load the exported VCL; see post 6. - A proxy strips the headers. Set Storefront Origin and read the "Origin sends edge cache headers" check.
- The page is not cacheable in Magento either. A block with
cacheable="false"in the layout makes the whole page uncacheable. Search your theme and extensions for it.
When cf-cache-status is BYPASS on a page that should cache
A bypass rule matched. Compare the path with Bypass Paths, check whether the request carried the X-Magento-Vary cookie (a visit to a non-default store view, currency or a login sets it, and it persists), and check for a query string while Cache Query Strings is No.
If the opposite happened and a checkout or account page came back HIT, a rule overrode Magento's headers. Look for a "Cache Everything" rule, a page rule, or an edge TTL override on the cache rule, remove it, and purge everything.
Once pages are cached, the next job is keeping them fresh. Post 3 covers purge modes, the queue consumer and the purge log.
If you would rather have someone set this up and prove it on the health page, our performance and infrastructure team does this work.
✦ FAQ
Does edge caching replace Magento's full page cache?+–
What TTL does Cloudflare use if Edge TTL is blank?+–
Can checkout be cached by accident?+–
Do I need to purge after changing Bypass Paths?+–
Does Vary Handling Cache key work on a Free or Pro plan?+–
Why does curl not show a Cache-Tag header on a cached page?+–

Shane Blandford
Founder of Orange Collar Media, a Denver ecommerce agency behind 800+ Magento and Shopify builds. In Magento since version 1.x - building, rescuing, and supporting revenue-critical stores since 2008.
✦ KEEP READING
Related from the Journal.
Why put Cloudflare in front of Magento: what a CDN does for a store, what it does not, and what breaks
What Cloudflare does for a Magento store: a CDN for static files, edge-cached HTML, DDoS and bot protection, a WAF, and the five settings that break checkout.

OCM Labs Cloudflare: free edge caching for Magento, on Magento's own terms
A free, open-source Magento module that caches storefront HTML at the Cloudflare edge using Magento's own full page cache rules, and purges by cache tag.

How to use Cloudflare development mode and analytics from the Magento admin
Turn Cloudflare development mode on before a theme deploy, run a quick purge and read Cloudflare analytics from the Magento admin with a free module.
