DEV Community

Magevanta
Magevanta

Posted on • Originally published at magevanta.com

Magento 2 CDN Setup: Optimize Static Content Delivery

Content Delivery Networks (CDNs) are one of the most impactful yet underutilized performance tools in the Magento 2 ecosystem. While most store owners obsess over backend optimizations — database tuning, indexer speed, PHP-FPM settings — the frontend delivery of static assets often remains a blind spot. This is a mistake. A well-configured CDN can reduce Time to First Byte (TTFB), cut bandwidth costs, and dramatically improve the user experience for global audiences.

In this guide, we'll walk through the complete CDN setup for Magento 2, covering static content, media files, and user-generated content. We'll also discuss advanced configuration for cache invalidation and HTTPS/TLS optimization.

Why CDN Matters for Magento 2

Magento 2 stores are asset-heavy. A typical product page loads dozens of JavaScript files, CSS bundles, product images, category thumbnails, and static theme assets. Without a CDN, every request hits your origin server, creating unnecessary load and increasing latency — especially for users geographically distant from your hosting location.

Key benefits of using a CDN with Magento 2:

  • Reduced latency: Edge servers deliver content from locations closer to the user
  • Origin offload: Static assets never hit your Magento server, freeing PHP-FPM workers
  • Bandwidth savings: Origin egress drops significantly
  • Improved Core Web Vitals: Faster LCP and reduced TTFB directly impact SEO
  • DDoS resilience: CDN edge absorbs traffic spikes

What Should Go Through the CDN?

A typical Magento 2 CDN setup handles three asset categories:

  • Static Content (/static/) — JS, CSS, theme assets, font files
  • Media (/media/) — Product images, category images, WYSIWYG uploads
  • User Content (/pub/media/) — Customer uploads, order PDFs, invoices

Do NOT CDN these paths:

  • /rest/ — API endpoints, dynamic
  • /checkout/ — Cart operations, dynamic
  • /customer/ — Account pages, session-based
  • /admin/ — Security risk

Step 1: Base URL Configuration

Magento 2 supports separate base URLs for static and media content. Configure these in Stores > Configuration > Web > Base URLs:

Base URL: https://magevanta.com/
Base URL for Static View Files: https://cdn.magevanta.com/static/
Base URL for User Media Files: https://cdn.magevanta.com/media/
Enter fullscreen mode Exit fullscreen mode

For multi-store setups, configure per-store base URLs under the store scope. Always use HTTPS for CDN URLs — modern browsers flag mixed-content warnings, and HTTP/2 requires TLS.

After changing base URLs, run a full cache flush:

bin/magento cache:flush
Enter fullscreen mode Exit fullscreen mode

Step 2: Static Content Deploy with Versioning

Magento's static content deployment (setup:static-content:deploy) generates versioned directories under pub/static/. The version hash changes with each deployment, making CDN cache invalidation automatic — the URL changes, so the CDN fetches fresh content.

Verify versioning is enabled:

bin/magento config:show dev/static/sign
Enter fullscreen mode Exit fullscreen mode

Should return 1. If not, enable it:

bin/magento config:set dev/static/sign 1
Enter fullscreen mode Exit fullscreen mode

With signing enabled, your static URLs look like:

https://cdn.magevanta.com/static/version1234567890/frontend/Magento/luma/en_US/css/styles.css
Enter fullscreen mode Exit fullscreen mode

When you deploy new static content, the version hash updates and the CDN automatically serves the new files.

Step 3: Cloudflare Configuration

Cloudflare is the most popular CDN choice for Magento stores due to its generous free tier and edge caching capabilities.

Page Rules

Create these page rules in order (Cloudflare evaluates top-down):

  1. *cdn.magevanta.com/static/* → Cache Level: Cache Everything, Edge TTL: 1 month
  2. *cdn.magevanta.com/media/* → Cache Level: Cache Everything, Edge TTL: 7 days
  3. *magevanta.com/checkout/* → Cache Level: Bypass
  4. *magevanta.com/customer/* → Cache Level: Bypass

Origin Configuration

  • SSL/TLS mode: Full (strict) — requires valid certificate on origin
  • Always Use HTTPS: On
  • Automatic HTTPS Rewrites: On
  • Brotli compression: On — better than gzip, roughly 15-20% smaller
  • HTTP/2: Enabled by default
  • HTTP/3 (QUIC): Enable for reduced latency on mobile

Cache Headers

Ensure your origin sends proper cache headers for static assets. Add to your Nginx configuration:

location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
    add_header X-Content-Type-Options nosniff;
    access_log off;
}

location /media/ {
    expires 7d;
    add_header Cache-Control "public, must-revalidate";
}
Enter fullscreen mode Exit fullscreen mode

The immutable directive tells browsers the file will never change — the version hash handles updates — allowing aggressive browser caching without stale content risk.

Step 4: Image Optimization

Most CDNs offer automatic image optimization. For Cloudflare:

  • Polish: Enable Lossy for product images, Lossless for logos and icons
  • WebP: Automatic conversion for supporting browsers
  • Mirage: Mobile image optimization that resizes for viewport

For Magento stores with thousands of product images, this alone can reduce image payload by 30-50%.

Nginx-Level WebP Fallback

If your CDN doesn't handle WebP conversion, serve it directly via Nginx with the ngx_http_image_filter_module or pre-generate WebP variants during setup:static-content:deploy using a custom deploy strategy.

Step 5: Cache Invalidation Strategy

Static content is easy — version hashes handle it. Media content requires explicit invalidation when products are updated.

Option A: Cloudflare API

After product import or mass update, purge specific paths:

PURGE_URLS='["https://cdn.magevanta.com/media/catalog/product/cache/*"]'

curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  --data "{\"files\":$PURGE_URLS}"
Enter fullscreen mode Exit fullscreen mode

Option B: Magento Cache Tags

Advanced setups can integrate CDN invalidation with Magento's cache tags. When Magento purges FPC for a product, trigger a CDN purge for that product's media paths. This requires custom module development using the clean_cache_by_tags event.

Option C: Stale-While-Revalidate

For high-traffic stores, consider stale-while-revalidate headers. The CDN serves the cached version immediately while fetching a fresh copy in the background. This eliminates cache-miss latency spikes during invalidation:

Cache-Control: public, max-age=86400, stale-while-revalidate=3600
Enter fullscreen mode Exit fullscreen mode

Step 6: Multi-Region CDN with Origin Shield

If your store serves multiple regions, enable Cloudflare's Origin Shield (or equivalent in other CDNs). Without it, each regional edge node independently fetches from origin on cache miss. With Origin Shield, a single intermediate cache layer absorbs misses:

  • Without shield: 200 edge nodes × 1% miss rate = 2 origin requests per asset
  • With shield: 200 edge nodes → 1 shield node → 1 origin request per asset

For stores running on limited origin infrastructure, this can prevent cache stampedes during product launches or sale events.

Step 7: Monitoring and Verification

After CDN deployment, verify configuration:

  1. Response headers: Check CF-Cache-Status header:

    • HIT — served from CDN edge
    • MISS — fetched from origin (first request)
    • DYNAMIC — not cached, check page rules
  2. Waterfall analysis: Use Chrome DevTools or WebPageTest to confirm static assets load from CDN domain and show cache hits.

  3. Origin bandwidth: Monitor your hosting panel — successful CDN offload drops static content bandwidth to near zero.

  4. Cache hit ratio: Aim for >95% hit ratio on static assets. Below that, review your page rules and cache headers.

Common Pitfalls

Mixed content warnings: If your base URL is HTTP but the page loads over HTTPS, browsers block assets. Always use HTTPS CDN URLs.

CORS issues for fonts: WOFF/2 font files served from a different domain need CORS headers:

location ~* \.(woff|woff2)$ {
    add_header Access-Control-Allow-Origin "*";
}
Enter fullscreen mode Exit fullscreen mode

Cookie forwarding: Ensure the CDN strips or doesn't forward cookies for static asset requests. Cookies prevent caching and expose session data.

Admin panel exposure: Never CDN admin URLs. Restrict admin access to origin IP whitelist.

Stale assets after deploy: If you're not using versioned URLs, users may see old CSS/JS after a deploy. Always enable dev/static/sign.

Performance Impact

A properly configured CDN typically delivers:

  • 30-50% reduction in page load time for global users
  • 60-80% reduction in origin bandwidth usage
  • LCP improvement of 0.5-1.5 seconds on image-heavy pages
  • TTFB reduction from 200-500ms to 20-50ms for cached assets

For a store doing $1M+ revenue, this directly translates to higher conversion rates — Amazon famously estimated every 100ms delay costs 1% in revenue.

Conclusion

CDN configuration is low-hanging fruit for Magento 2 performance. The setup is straightforward — base URL changes, Cloudflare page rules, and proper cache headers — yet the impact is outsized. For stores with international customers or heavy static asset loads, a CDN moves from "nice to have" to essential infrastructure.

Start with static and media content, monitor your cache hit ratio, then expand to advanced features like image optimization and automatic purge integration. Your origin server — and your users — will thank you.

Top comments (0)