Magento 2 CDN: Cloudflare vs Fastly Setup Guide
A CDN in front of Magento 2 can take most static traffic off your servers, bring assets closer to visitors and absorb bot spikes. It can also break checkout, show one customer's cart to another, or serve old CSS for a week. The difference is in what you let the CDN cache and how it gets purged. This article compares the two most common choices for Magento Open Source and Adobe Commerce 2.4.8, Fastly and Cloudflare, and explains how to set each up safely.
What a CDN should cache
A Magento storefront has three kinds of responses:
- Static assets under
/static/: CSS, JavaScript, fonts, theme images. They are versioned through static file signing, so the URL changes on every deploy. Safe to cache for a very long time. - Media under
/media/: product images, category images, CMS uploads. They change rarely, and resized catalog images have their own cache paths. Safe to cache for a long time. - HTML and API responses: pages, AJAX calls, REST and GraphQL. Some are public and cacheable, many are private. This is where mistakes happen.
Caching static and media at the edge is low risk and gives most of the bandwidth benefit. Caching HTML at the edge gives the biggest speed gain for visitors, but only works if the CDN understands Magento's cache rules: which pages are cacheable, how they vary per customer group and currency, and how to purge them by tag.
Fastly: a full page cache at the edge
Fastly runs on Varnish, and its integration with Magento comes through the Fastly CDN module (fastly/magento2). On Adobe Commerce on cloud infrastructure, Fastly is part of the platform. On Magento Open Source or self hosted Adobe Commerce, you install the module and get your own Fastly account.
The module adds Fastly as an option for the full page cache application. Once selected and configured with your service ID and API token, it:
- Uploads a VCL to your Fastly service that follows Magento's caching rules, similar to the VCL Magento generates for Varnish.
- Translates Magento's cache tags into Fastly surrogate keys, so a product save purges exactly the pages that show that product, at the edge.
- Handles the
X-Magento-Varycookie so pages are cached per context. - Offers extra features in the admin, such as image optimization settings, edge modules and blocking rules. Which ones are available depends on your Fastly plan.
In this setup Fastly replaces Varnish as the full page cache. You do not need a local Varnish behind it, although some setups keep one as a shield.
composer require fastly/magento2
bin/magento module:enable Fastly_Cdn
bin/magento setup:upgrade
Configure it under Stores, Configuration, Advanced, System, Full Page Cache, choose Fastly CDN as the caching application, enter the credentials, then upload the VCL from the admin. Test on staging with a separate Fastly service first. A wrong VCL upload affects all traffic at once.
Things to watch with Fastly
- Purges are fast, but a full purge empties the edge everywhere. Avoid automated full purges on every deploy unless your traffic can take the cold cache.
- The hit rate depends on the same things as with Varnish: blocks marked
cacheable="false"in layout, too many vary values, and query parameters that make every URL unique. Read the Varnish full page cache guide, almost all of it applies to Fastly. - Keep the module updated with your Magento version. It hooks into cache invalidation, and an outdated version can leave stale pages at the edge.
Cloudflare: static first
Cloudflare works differently. It is a reverse proxy and CDN in front of your origin, with no official Magento module that maps cache tags to purges. Out of the box, Cloudflare caches responses based on file extension and does not cache HTML. For Magento, that default is a reasonable starting point: static files and media are cached at the edge, HTML goes to your origin, where Varnish serves it.
A common setup:
- DNS for the store points to Cloudflare in proxied mode.
- Cloudflare caches
/static/and/media/, with a long edge cache TTL set through a cache rule. - HTML passes through to your origin, where Varnish acts as the full page cache.
- Cloudflare also provides TLS at the edge, DDoS protection and bot rules.
Why not cache HTML in Cloudflare?
You can, with cache rules that mark HTML as eligible for cache. The problem is purging and variation. Magento does not tell Cloudflare when a product changes, so cached pages stay stale until their TTL ends or you purge by hand. Cloudflare also does not know about the X-Magento-Vary cookie unless you configure custom cache keys, and getting that wrong means customers in one group see another group's prices. Some third party modules connect Magento purges to the Cloudflare API. If you go that way, test logged in states, customer groups, currencies and the cart carefully. For most stores, keeping HTML in Varnish and using Cloudflare for static, media and protection is the safer setup.
Cloudflare settings that cause trouble
- Rocket Loader changes how JavaScript loads. It conflicts with RequireJS on Luma themes and with the inline initialization scripts Magento uses. Keep it off for the store.
- Email obfuscation and other HTML rewriting features can alter Knockout templates or inline JSON. If something breaks only through Cloudflare, try turning these off.
- Caching everything rules that include
/checkout/,/customer/,/rest/or/graphqlwithout a careful bypass will leak private data. Never cache those. - Bot protection challenges on API paths can break integrations and payment callbacks. Exclude webhook and API paths from challenges.
Real visitor IP behind a CDN
With any CDN in front, your server sees the CDN's IP addresses as the client. Magento features that depend on the remote IP, such as admin IP restrictions, rate limiting and fraud checks in payment extensions, then see the wrong address. Fix it at the web server. For Cloudflare, nginx can trust the Cloudflare ranges and read their header:
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
real_ip_header CF-Connecting-IP;
This is only an excerpt. Cloudflare publishes the full list of IPv4 and IPv6 ranges, and you should include all of them and keep the list updated. Fastly also publishes its ranges, and sends the client IP in the Fastly-Client-IP header. The nginx configuration guide covers the realip setup in more detail.
Serving static and media from a separate host
Magento can build static and media URLs on a different host from the storefront, using the base URL settings for static view files and media files under Stores, Configuration, General, Web, Base URLs. The config paths are web/unsecure/base_static_url, web/secure/base_static_url, web/unsecure/base_media_url and web/secure/base_media_url.
bin/magento config:set web/secure/base_static_url https://cdn.example.com/static/
bin/magento config:set web/secure/base_media_url https://cdn.example.com/media/
This is useful with a pull CDN that is not in front of the whole site. If the whole domain already runs through Cloudflare or Fastly, a separate host adds a DNS lookup and a TLS connection for little gain. With HTTP/2 and HTTP/3, serving everything from one host is usually faster.
If you use a separate host, set CORS headers for fonts on the CDN or origin. Browsers block web fonts from another origin without them, and the symptom is missing icon fonts on the storefront.
Deploys and cache busting
Static file signing gives every deploy new static URLs, so the CDN fetches fresh files without a purge. Keep dev/static/sign enabled. Media files do not have versioned URLs. If you replace an image under the same file name, purge that path at the CDN.
After a deploy that changes templates, the HTML still has to be refreshed. With Fastly that is a Magento cache clean, which triggers the purge. With Cloudflare in front of Varnish, the Magento cache clean purges Varnish, and Cloudflare is not involved because it was not caching HTML.
Fastly or Cloudflare?
- On Adobe Commerce cloud, Fastly is already there. Use it.
- If you want full page caching at the edge with proper tag purging, Fastly with its Magento module is the established option.
- If you want a simple, low cost layer for static files, media, TLS and protection, keeping Varnish as the page cache, Cloudflare works well.
Whichever you choose, measure from real visitors before and after, for example with field data in the Core Web Vitals report, and check that cart, checkout and customer pages behave correctly through the CDN.
FAQ
Can Cloudflare cache Magento 2 HTML pages?
It can with cache rules, but Magento does not purge Cloudflare on product changes and per group pricing needs custom cache keys. Most stores keep HTML in Varnish and use Cloudflare for static files and media.
Do I need Varnish if I use Fastly?
No. With the Fastly module, Fastly is the full page cache application and handles caching and tag based purges at the edge.
Why does Magento show the wrong visitor IP behind a CDN?
The server sees the CDN as the client. Configure the realip module in nginx to trust the CDN ranges and read its client IP header.
Should I turn on Cloudflare Rocket Loader for Magento?
No. It changes how scripts load and conflicts with RequireJS and Magento's inline initialization scripts.
I am available for freelance Magento and Adobe Commerce work, including CDN and caching setups. If you need help with this, get in touch.
Related articles
Magento 2 Product Images Optimization: Resize, Cache and LCP
Tune Magento 2 product images: view.xml sizes, the resize command, the image cache, upload quality, CDN resizing and LCP fixes for listing and product pages.
Magento 2 Blackfire Profiling: Pages, CLI and Tests
Profile Magento 2 with Blackfire: probe and agent setup, profiling pages and bin/magento commands, reading call graphs and adding performance assertions.
Magento 2 Cache Types Explained: Clean, Flush, Custom
What each Magento 2 cache type stores, the real difference between cache:clean and cache:flush, invalidated caches, and how to add your own cache type.
Magento 2 Code Review Checklist for Pull Requests
A practical Magento 2 code review checklist: DI and architecture, performance traps, security and escaping, database changes, frontend, tests and deploy impact.