How to Set Up a CDN for WordPress (Cloudflare, BunnyCDN, KeyCDN)

A CDN cuts TTFB for global visitors and reduces server load. How to set up Cloudflare, BunnyCDN, or KeyCDN for WordPress correctly.

Dobromir Dechev
Dobromir WordPress agency owner

A CDN (Content Delivery Network) distributes your static assets - images, CSS, JavaScript, fonts - across servers worldwide. A visitor in Tokyo gets these files from a CDN node in Singapore, not from your server in Frankfurt. Load times drop by hundreds of milliseconds for distant visitors.

For WordPress, a CDN also reduces load on your origin server. Images served by a CDN never touch PHP or the database.

Here are the three most useful CDN options for WordPress sites and how to configure each one correctly.


Option 1 - Cloudflare (free tier, proxy + CDN)

Cloudflare is the most widely used option because it is free, fast to set up, and does more than just CDN - it is also a DNS provider, WAF, and DDoS mitigation layer.

How Cloudflare works with WordPress

Unlike a traditional CDN (which only handles static assets), Cloudflare is a full reverse proxy. All traffic goes through Cloudflare's network before reaching your server. Cloudflare caches static files and optionally caches HTML pages, adds security rules, and scrubs malicious traffic.

Setup

  1. Create a Cloudflare account and add your domain
  2. Change your nameservers to Cloudflare's nameservers (provided during setup). This is the crucial step - Cloudflare must be your DNS provider to act as a proxy
  3. After nameserver propagation (up to 24 hours), your site traffic routes through Cloudflare

Configure SSL mode correctly

This is the most critical Cloudflare setting for WordPress. Go to SSL/TLS > Overview:

  • Off: Everything is HTTP. Never use this.
  • Flexible: Cloudflare uses HTTPS between visitors and Cloudflare, but HTTP between Cloudflare and your server. This causes redirect loops if WordPress is configured to force HTTPS. Do not use this unless you have no SSL certificate on your server.
  • Full: Cloudflare uses HTTPS to your server, but does not validate your SSL certificate. Works even with self-signed certs.
  • Full (strict): Cloudflare validates your origin certificate. Requires a valid certificate (Let's Encrypt or Cloudflare Origin Certificate). This is the correct setting for production sites.

If you see ERR_TOO_MANY_REDIRECTS after adding your site to Cloudflare, the SSL mode is set to Flexible while WordPress forces HTTPS. Fix by changing to Full.

Configure caching

Cloudflare caches static assets by default. To cache HTML pages (the biggest performance win):

In Caching > Configuration:

  • Set "Caching Level" to Standard
  • Set "Browser Cache TTL" to "Respect Existing Headers" (lets your server control cache durations)

For full-page caching, create a Page Rule (or use a Cloudflare Workers script) to cache everything except logged-in sessions and WooCommerce cart/checkout:

Page Rules > Add a rule:

  • URL: yourdomain.com/*
  • Cache Level: Cache Everything
  • Edge Cache TTL: 1 hour

Add bypass rules for dynamic pages:

  • yourdomain.com/wp-admin/* > Cache Level: Bypass
  • yourdomain.com/cart/ > Cache Level: Bypass
  • yourdomain.com/checkout/* > Cache Level: Bypass
  • yourdomain.com/my-account/* > Cache Level: Bypass

WordPress plugin for Cloudflare integration

Install the Cloudflare official plugin or WP Rocket's Cloudflare integration. These plugins allow you to purge the Cloudflare cache from within WordPress when you publish or update content - without manually going to the Cloudflare dashboard.

Cloudflare gotchas

Rocket Loader: Cloudflare's Rocket Loader asynchronously loads JavaScript. It can break sliders, page builders, and WooCommerce functionality. If you notice JS errors after enabling Cloudflare, disable Rocket Loader first.

Auto Minify: Cloudflare can minify HTML, CSS, and JS. This can conflict with your caching plugin's own minification. Use one or the other, not both.

Proxy status in DNS: Records with the orange cloud icon are proxied through Cloudflare. The A record for your domain must have the orange cloud enabled for the CDN to work. Mail records (MX), CNAME records for external services (Stripe webhooks, etc.) should be DNS-only (grey cloud).


Option 2 - BunnyCDN (best performance per pound)

BunnyCDN is a specialist CDN focused purely on file delivery. It is significantly cheaper than AWS CloudFront and comparable in performance to Cloudflare CDN for static assets.

How it differs from Cloudflare

BunnyCDN is a pull CDN, not a proxy. Your origin server still handles all HTML and PHP requests. BunnyCDN only serves static files (images, CSS, JS, fonts) via a CDN URL or a custom CDN subdomain.

This is simpler to configure and does not affect server-side logic, redirects, or dynamic content.

Setup with WordPress

  1. Create a BunnyCDN account and add a Pull Zone

  2. Set the origin URL to your WordPress site (e.g., https://yourdomain.com)

  3. BunnyCDN gives you a CDN hostname: yoursitename.b-cdn.net

  4. Optionally, create a CNAME in your DNS: cdn.yourdomain.comyoursitename.b-cdn.net

  5. Install the BunnyCDN plugin for WordPress or configure your caching plugin to use the CDN URL:

In WP Rocket > CDN tab: enter cdn.yourdomain.com as your CDN URL. WP Rocket rewrites all static asset URLs to point to the CDN.

In W3 Total Cache > CDN tab: select "Generic Mirror" and enter the CDN hostname.

Performance

BunnyCDN's network covers 100+ edge locations. For static asset delivery, it is competitive with Cloudflare and significantly cheaper at scale ($0.01/GB in Europe/NA). For a typical site serving 100GB/month of images, that is $1/month.


Option 3 - KeyCDN

KeyCDN is another specialist CDN with particularly strong European coverage and transparent pricing. Similar to BunnyCDN in concept.

Setup

  1. Create a Pull Zone with your origin URL
  2. Enable the WordPress plugin or configure via WP Rocket/W3TC
  3. KeyCDN provides detailed analytics on cache hit rates and bandwidth per zone

When to choose KeyCDN over BunnyCDN

KeyCDN has slightly better coverage in Central/Eastern Europe and offers image processing features (resizing, WebP conversion on-the-fly). If your audience is heavily European and you want server-side image optimisation, KeyCDN is worth evaluating.


Verifying the CDN is working

After setup, verify assets are actually being served from the CDN:

  1. Open the Network tab in browser DevTools
  2. Load the page and filter by Images or All
  3. Click an image and check the Response Headers
  4. You should see Server: BunnyCDN or CF-Cache-Status: HIT (Cloudflare)

If assets still show your origin server in the response headers, the CDN URL is not being applied to the HTML output. Check your caching plugin's CDN configuration.

Check cache hit rate

In your CDN dashboard, the cache hit rate should be above 90% for static assets within 24 hours of going live. A low hit rate means:

  • Cache TTL is set too short
  • Assets are not being cached (check for no-cache headers on your origin)
  • The CDN is not receiving the asset requests

CDN + WordPress cache: combined strategy

For maximum performance, use both:

  1. Server-level caching (Nginx FastCGI cache, WP Rocket, or LiteSpeed Cache): caches HTML pages on your server so PHP is not invoked for every visitor
  2. CDN (Cloudflare, BunnyCDN): caches static assets globally so images and CSS load fast from the visitor's nearest edge node

Together, a returning visitor to your site may have:

  • The HTML served from your server's cache (TTFB under 50ms)
  • Images served from a CDN node 20ms away from them
  • CSS and JS from browser cache (if the browser has visited before)

A first page load from a global visitor should be under 2 seconds even with hundreds of kilobytes of images.


Was this article helpful?