The recommended Cloudflare cache rules for Magento, applied from the admin or written by hand
Apply from the admin or the CLI
Open System > Cloudflare > Dashboard > Health and click Apply recommended cache rules, or run:
bin/magento ocmlabs:cloudflare:rules:apply --dry-runbin/magento ocmlabs:cloudflare:rules:applyYou get a diff first: rules kept, added, changed and removed. Applying needs the OCMLabs_Cloudflare::settings_write ACL resource in the admin and an API token with Zone:Cache Rules:Edit. Running it twice changes nothing the second time.
The module only touches rules whose description starts with [OCMLabs]. Your own rules stay exactly where they are, and the diff shows them as kept, with a note if they sit above the module’s rules and might override them. Each module rule name ends with the Magento website code, for example [OCMLabs] Cache storefront HTML (base), so several Magento websites can share one zone: applying the rules for one website leaves the other websites’ [OCMLabs] rules alone.
The rules, in order
Cloudflare evaluates cache rules top to bottom, and a later match overrides an earlier one for each setting it sets. The order below is the order the module writes, and the “Bypass rules” health check confirms the bypass rules sit below the cache rule.
| # | Rule | What it does |
|---|---|---|
| 1 | Cache storefront HTML | Everything on the storefront hosts is eligible for cache. Edge TTL and browser TTL respect the origin headers, so Magento’s Cache-Control decides what is actually cached and for how long. |
| 2 | Static assets | / and / are cached for a year at the edge and in the browser. Safe because Magento versions static URLs and image variants live at their own paths. |
| 3 | Bypass protected paths | Every path in Bypass Paths, plus the _ and _ store switch URLs. |
| 4 | Bypass non-GET | Anything that is not a GET request. |
| 5 | Bypass on vary cookie | Requests carrying the X-Magento-Vary cookie. Only written when Vary Handling is Bypass. |
| 6 | Bypass query strings | Requests with a query string, except static and media paths. Only written when Cache Query Strings is No. |
With Vary Handling set to Cache key on an Enterprise zone, rule 5 is replaced by a custom cache key on rule 1 that includes the X-Magento-Vary cookie, so store views, currencies and customer groups are cached as separate variants. On any other plan the module falls back to the bypass rule and says so in the preview.
If you have rules of your own, put the OCMLabs rules above them unless you mean your rule to override these.
Writing the rules by hand
Use this when your API token does not have Zone:Cache Rules:Edit, or when you want to see exactly what the module writes. In Cloudflare go to your zone > Caching > Cache Rules > Create rule. For each rule, choose Edit expression, paste the expression, and set the actions listed.
Before you paste:
- Replace
www.example.comwith your storefront host. For several hosts, list them inside the braces separated by spaces:{"www.example.com" "example.com"}. - Replace
/adminin rule 3 with your real admin path (thefrontNameinapp/etc/env.php). - Rule 3 uses the default Bypass Paths. If you changed that list in Magento, change the expression to match. Each path needs both the
eqterm and thestarts_withterm. - Name each rule exactly as shown, starting with
[OCMLabs]and ending with your Magento website code in brackets. If you later give the tokenZone:Cache Rules:Editand runrules:apply, the module takes over the[OCMLabs]rules for that website and leaves everything else alone.
1. [OCMLabs] Cache storefront HTML (base)
(http.host in {"www.example.com"})- Cache eligibility: Eligible for cache
- Edge TTL: Use cache-control header if present (respect origin)
- Browser TTL: Respect origin TTL
- Enterprise with Vary Handling set to Cache key only: Cache key > Cookie > include
X-Magento-Vary, and skip rule 5
2. [OCMLabs] Static assets (base)
(http.host in {"www.example.com"}) and (starts_with(http.request.uri.path, "/static/") or starts_with(http.request.uri.path, "/media/"))- Cache eligibility: Eligible for cache
- Edge TTL: Ignore cache-control header and use this TTL, 1 year (31536000 seconds)
- Browser TTL: Override origin, 1 year (31536000 seconds)
3. [OCMLabs] Bypass protected paths (base)
(http.host in {"www.example.com"}) and ((lower(http.request.uri.path) eq "/checkout" or starts_with(lower(http.request.uri.path), "/checkout/") or lower(http.request.uri.path) eq "/customer" or starts_with(lower(http.request.uri.path), "/customer/") or lower(http.request.uri.path) eq "/sales" or starts_with(lower(http.request.uri.path), "/sales/") or lower(http.request.uri.path) eq "/wishlist" or starts_with(lower(http.request.uri.path), "/wishlist/") or lower(http.request.uri.path) eq "/paypal" or starts_with(lower(http.request.uri.path), "/paypal/") or lower(http.request.uri.path) eq "/rest" or starts_with(lower(http.request.uri.path), "/rest/") or lower(http.request.uri.path) eq "/graphql" or starts_with(lower(http.request.uri.path), "/graphql/") or lower(http.request.uri.path) eq "/admin" or starts_with(lower(http.request.uri.path), "/admin/") or lower(http.request.uri.path) eq "/downloadable" or starts_with(lower(http.request.uri.path), "/downloadable/") or lower(http.request.uri.path) eq "/newsletter/subscriber" or starts_with(lower(http.request.uri.path), "/newsletter/subscriber/") or lower(http.request.uri.path) eq "/review/product/post" or starts_with(lower(http.request.uri.path), "/review/product/post/") or lower(http.request.uri.path) eq "/catalogsearch/advanced/result" or starts_with(lower(http.request.uri.path), "/catalogsearch/advanced/result/") or lower(http.request.uri.path) eq "/contact" or starts_with(lower(http.request.uri.path), "/contact/")) or (http.request.uri.query contains "___store=" or http.request.uri.query contains "___from_store="))- Cache eligibility: Bypass cache
4. [OCMLabs] Bypass non-GET (base)
(http.host in {"www.example.com"}) and (http.request.method ne "GET")- Cache eligibility: Bypass cache
5. [OCMLabs] Bypass on vary cookie (base)
Only when Vary Handling is Bypass.
(http.host in {"www.example.com"}) and (http.cookie contains "X-Magento-Vary=") and (not (starts_with(http.request.uri.path, "/static/") or starts_with(http.request.uri.path, "/media/")))- Cache eligibility: Bypass cache
6. [OCMLabs] Bypass query strings (base)
Only when Cache Query Strings is No.
(http.host in {"www.example.com"}) and (http.request.uri.query ne "") and (not (starts_with(http.request.uri.path, "/static/") or starts_with(http.request.uri.path, "/media/")))- Cache eligibility: Bypass cache
Check your work
Run bin/magento ocmlabs:cloudflare:health or click Run checks now on the Health tab. The Cache rules group checks that the storefront cache rule exists, the bypass rules exist and sit below it, the vary cookie is handled, POSTs are not cached and the rule’s edge TTL matches the module’s.
Do not add a “Cache Everything” rule or set an edge TTL override on rule 1. Either one makes Cloudflare ignore Magento’s private, no-store and cache checkout and account pages.