A CDN (content delivery network) stores copies of your site’s files on servers around the world, so visitors download them from a nearby location. For WordPress, a CDN cuts load times for distant visitors, reduces bandwidth and CPU on your VPS, and can absorb traffic spikes. There are two main ways to add one.
Background: CDN for websites.
Two approaches
| Full-site proxy (e.g. Cloudflare) | Asset pull CDN (e.g. BunnyCDN, KeyCDN, CloudFront) | |
|---|---|---|
| How it works | DNS points to the CDN; all traffic goes through it | Only static files load from cdn.example.com |
| Setup | Change nameservers or DNS records | Plugin or rewrite rules for asset URLs |
| Caches HTML | Optional (with cache rules) | No |
| Hides origin IP / DDoS filtering | Yes | No |
| Typical use | Most sites | Sites that want to keep DNS and HTML direct |
Option 1: Cloudflare in front of WordPress
- Add your site to Cloudflare, and switch nameservers (or use a CNAME setup on paid plans).
- Set SSL/TLS → Full (strict), with a valid certificate on your server (Let’s Encrypt or a Cloudflare origin certificate). Never use “Flexible”: it causes redirect loops in WordPress. See WordPress too many redirects.
- Static assets (CSS, JS, images, fonts) are cached automatically.
- Optional HTML caching: add a cache rule to cache everything, except:
/wp-admin/*,/wp-login.php, and/wp-json/*if it’s dynamic;- requests with cookies
wordpress_logged_in_*,wp-postpass_*,woocommerce_items_in_cart,comment_author_*; - cart, checkout and account pages on WooCommerce.
- Purge the cache when content changes: the Cloudflare plugin, or your caching plugin’s Cloudflare integration, can do this automatically.
Detailed guide: using Cloudflare with a VPS.
Restore real visitor IPs
Behind Cloudflare, your server sees Cloudflare’s IPs. Configure Nginx’s real_ip module with Cloudflare’s IP ranges, so logs, Fail2ban and security plugins see real visitors. See real IP behind Cloudflare.
Lock down the origin
Optionally allow HTTP/HTTPS only from Cloudflare’s IP ranges at your firewall, so attackers can’t bypass the CDN. Keep the list updated.
Option 2: asset pull CDN
- Create a pull zone at your CDN provider with your site as the origin (
https://example.com). You get a hostname such asexample.b-cdn.net. - Optionally add a CNAME
cdn.example.com→ the CDN hostname, and enable SSL for it at the CDN. - Rewrite asset URLs in WordPress, using either:
- your caching plugin’s CDN setting (WP Rocket, W3 Total Cache, LiteSpeed Cache, and others have one), or
- the CDN provider’s plugin (for example the bunny.net plugin), or
- a small plugin like CDN Enabler.
- Exclude
.phpand admin paths. Onlywp-contentandwp-includesassets should go to the CDN.
Fonts loaded from another domain need a CORS header:
location ~* \.(woff2?|ttf|eot)$ {
add_header Access-Control-Allow-Origin "*";
expires 30d;
}
Make your origin CDN-friendly
- Send long Cache-Control headers for static files, so the CDN and browsers keep them. See Nginx static file caching.
- Serve modern image formats (WebP or AVIF), and right-size images. See WordPress image optimization.
- Keep a fast origin with page caching, because the CDN still fetches uncached HTML from your server. See Nginx FastCGI cache.
Test it
curl -sI https://example.com/wp-content/themes/yourtheme/style.css | grep -iE 'cf-cache-status|x-cache|cache-control|age'
cf-cache-status: HIT(Cloudflare) orx-cache: HIT(many CDNs) means it was served from the edge.- Check from several regions with online tools, and compare Time to First Byte (TTFB) before and after.
- Log in and check that the admin bar and your own changes appear (no cached logged-in pages).
Common problems
| Problem | Fix |
|---|---|
| Redirect loop after enabling Cloudflare | Use SSL mode “Full (strict)”, not “Flexible” |
| Logged-in pages shown to visitors | Bypass cache for WordPress login cookies |
| Old CSS after changes | Purge the CDN cache; make sure ?ver= query strings are kept |
| Fonts blocked | Add Access-Control-Allow-Origin for font files |
| Every visitor has the same IP in logs | Configure real IP restoration |
Does a CDN replace good hosting?
No. A CDN speeds up delivery, but uncached pages, the admin area, search, and WooCommerce checkout still depend on your server. Choose a VPS location close to your main audience, and use the CDN for everyone else. See choosing a VPS location and WordPress VPS hosting.
Related: Core Web Vitals and server performance and WordPress performance tuning.