CDN + Cloud Hosting: How to Configure Them Together the Right Way

Written by:

·

Last Updated on:

·

HostingGuider uses affiliate links. We may earn a commission if you purchase through them, at no extra cost to you.

Most CDN tutorials get one critical thing wrong.

They tell you to enable Flexible SSL. This means traffic between the CDN and your origin server travels unencrypted over plain HTTP. Your visitors see a padlock in their browser. Their data is exposed between the CDN edge and your server. The padlock is real. The security is not.

That is the most dangerous mistake in CDN configuration. It is the default in many tutorials because it requires less setup. This guide does not cut that corner.

This guide covers the correct way to configure a CDN in front of cloud hosting. Every decision is explained. Every wrong setting is flagged before you make it. By the end, you have a CDN and origin server that work correctly, securely, and efficiently together.

The guide uses Cloudflare as the primary example. Cloudflare is the most widely used CDN for WordPress and cloud-hosted sites. Alternative CDN options are covered where the approach differs.

Key Takeaways

  • Never use Flexible SSL. Always use Full (Strict) SSL
  • The CDN sits between your visitors and your origin server. Every configuration decision must account for both sides
  • WordPress requires specific cache bypass rules for logged-in users, wp-admin, and WooCommerce cart
  • Real visitor IPs must be restored on the origin server or logs show the CDN IP for all traffic
  • Origin lockdown is a required security step that most tutorials skip entirely
  • Test every setting after applying it. Do not assume the configuration works until you verify it

How CDN + Cloud Hosting Works Together

Without a CDN, a visitor’s request travels directly to your origin server:

Visitor → DNS → Origin Server → Response

With a CDN in front:

Visitor → DNS → CDN Edge (nearest PoP) → Origin Server → CDN Edge → Visitor

The CDN inserts itself into the request path. For cached content, the origin server is bypassed entirely:

Visitor → DNS → CDN Edge Cache → Visitor (origin server not contacted)

This is the performance gain. Instead of your London server responding to a visitor in Singapore (100ms+ network round trip), a CDN edge server in Singapore responds in under 10ms.

The CDN also absorbs traffic. DDoS attacks hit the CDN edge, not your origin server directly. A CDN with 200+ global data centres can absorb attack traffic that would overwhelm any single origin server.

Global CDN architecture infographic showing edge nodes, cache hits, and cache misses
How CDN edge servers reduce origin server load and improve content delivery speed

The key principle: the CDN and origin server must be configured to trust each other correctly. Misconfiguration at either end breaks the setup. This guide covers both sides.

Phase 1: Choose Your CDN

Different CDNs suit different needs. Here is an honest comparison of the main options:

CDNBest ForFree TierPricing Model
CloudflareWordPress, SMB, DDoS protectionYes, generousFlat fee (Pro $20/month)
Bunny CDNSimple static asset deliveryNoPay per GB ($0.005-0.01/GB)
AWS CloudFrontAWS ecosystem, fine-grained control1TB free first yearPay per GB + requests
FastlyDeveloper-controlled, real-time purgingNoPay per GB
Rocket.netCloudflare Enterprise at managed WP priceNoPart of hosting plan
BunnyCDN Perma-CacheLarge file and media deliveryNoPay per GB

For most WordPress sites on cloud hosting: Cloudflare free or Pro tier is the right choice. The free tier includes CDN, DDoS protection, SSL, and basic WAF. The Pro tier adds image optimisation and more WAF rules.

For simple static asset CDN without DNS proxying: Bunny CDN at $0.005-0.01 per GB is the most cost-effective. It does not require changing your nameservers.

For sites already on AWS infrastructure: CloudFront integrates directly with other AWS services.

For fully managed setup with enterprise CDN built in: Rocket.net includes Cloudflare Enterprise as part of their managed WordPress hosting. No CDN configuration required. Kinsta includes their own CDN with 260+ global locations.

This guide focuses on the Cloudflare + cloud hosting stack. The concepts translate to other CDNs with provider-specific UI differences.

Phase 2: Add Your Site to Cloudflare

Step 2.1: Create a Cloudflare Account

Go to cloudflare.com and create an account.

Click Add a Site. Enter your domain name. Choose your plan. The Free plan covers everything this guide configures.

Step 2.2: Cloudflare Scans Your DNS

Cloudflare scans your current DNS records and imports them automatically. Review the imported records carefully.

Confirm these records are present and correct:

  • A record for @ (root domain) pointing to your origin server IP
  • A record for www pointing to your origin server IP
  • MX records if you use email through a third party
  • Any other CNAME records for subdomains

The orange cloud icon next to a record means Cloudflare is proxying that traffic (CDN is active). The grey cloud means DNS-only (CDN is not active for that record).

For your web traffic, both the @ and www A records should show an orange cloud.

Step 2.3: Update Your Nameservers

Cloudflare gives you two nameserver addresses. They look like:

alice.ns.cloudflare.com
bob.ns.cloudflare.com

Log into your domain registrar. Find the nameserver settings. Replace your current nameservers with the two Cloudflare provides.

Nameserver changes take up to 24 hours to propagate globally. Cloudflare sends an email when your site is active on their network.

Verify nameserver propagation:

dig NS yourdomain.com +short

The output should show Cloudflare nameservers. Until it does, Cloudflare is not yet controlling your DNS.

Phase 3: SSL Configuration (The Most Critical Step)

This phase is where most setups go wrong. Read it carefully before touching any settings.

The SSL Modes Explained

Cloudflare has four SSL modes. Three of them are suitable for production. One of them is dangerous.

ModeVisitor to CloudflareCloudflare to OriginUse Case
OffHTTP onlyHTTPNever. Exposes all data
FlexibleHTTPSHTTPNever. False sense of security
FullHTTPSHTTPS (any cert)Acceptable but not ideal
Full (Strict)HTTPSHTTPS (valid cert only)Always use this

Flexible SSL is the wrong choice. Traffic between Cloudflare and your origin server is plain HTTP. An attacker with access to the network path between Cloudflare and your origin can intercept all traffic. Your visitors see HTTPS and trust the connection. Their data is not protected end-to-end.

SSL certificates and what they actually protect explains the full encryption chain.

Full (Strict) is the right choice. Traffic is encrypted with a valid certificate all the way from the visitor to your origin server. This is true end-to-end encryption.

Step 3.1: Get an Origin Certificate

For Full (Strict) mode, your origin server needs a valid SSL certificate. You have two options.

Option A: Cloudflare Origin Certificate (recommended)

Cloudflare provides free origin certificates that are trusted by their edge servers for up to 15 years. They are not trusted by browsers directly but they do not need to be. Only Cloudflare needs to trust them.

In your Cloudflare dashboard:

  1. Go to SSL/TLS
  2. Click Origin Server
  3. Click Create Certificate
  4. Choose RSA 2048 or ECDSA P-256
  5. Add your domain and www.yourdomain.com
  6. Choose validity period (15 years is fine for origin certificates)
  7. Click Create

Download both the Certificate and the Private Key. You need both on your origin server.

On your origin server, create the certificate files:

sudo nano /etc/ssl/cloudflare-origin.pem

Paste the certificate content. Save.

sudo nano /etc/ssl/cloudflare-origin.key

Paste the private key. Save.

Set correct permissions:

sudo chmod 644 /etc/ssl/cloudflare-origin.pem
sudo chmod 600 /etc/ssl/cloudflare-origin.key
sudo chown root:root /etc/ssl/cloudflare-origin.pem /etc/ssl/cloudflare-origin.key

Configure Nginx to use the origin certificate:

sudo nano /etc/nginx/sites-available/yourdomain.com

Update the server block:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name yourdomain.com www.yourdomain.com;

    ssl_certificate /etc/ssl/cloudflare-origin.pem;
    ssl_certificate_key /etc/ssl/cloudflare-origin.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    # rest of your configuration...
}

Test and reload:

sudo nginx -t
sudo systemctl reload nginx

Option B: Let’s Encrypt Certificate

A standard Let’s Encrypt certificate also works for Full (Strict) mode. If you already have Let’s Encrypt configured, this option requires no additional setup.

Step 3.2: Set SSL Mode to Full (Strict)

In Cloudflare dashboard:

  1. Go to SSL/TLS
  2. Click Overview
  3. Choose Full (Strict)

This takes effect immediately. Verify your site still loads:

curl -I https://yourdomain.com

You should see HTTP/2 200 and response headers. If you see an SSL error, your origin certificate is misconfigured. Check the Nginx error log:

sudo tail -50 /var/log/nginx/error.log

Step 3.3: Enable HSTS

HSTS (HTTP Strict Transport Security) tells browsers to always use HTTPS for your domain. It prevents SSL stripping attacks.

In Cloudflare dashboard:

  1. Go to SSL/TLS
  2. Click Edge Certificates
  3. Find HTTP Strict Transport Security (HSTS)
  4. Enable HSTS with these settings:
    • Status: Enabled
    • Max Age: 6 months (or 12 months once confirmed working)
    • Include subdomains: Yes (if all subdomains use HTTPS)
    • Preload: No (start without this, add later)

Phase 4: Real IP Restoration on the Origin Server

With CDN active, every request your origin server receives comes from a Cloudflare IP address, not the visitor’s IP. Your logs fill with Cloudflare IP addresses. WordPress security plugins ban the wrong IPs. GeoIP features stop working.

You must configure the origin server to restore real visitor IPs from the request headers Cloudflare provides.

The Headers Cloudflare Sends

Cloudflare adds these headers to every forwarded request:

HeaderContains
CF-Connecting-IPReal visitor IP address
X-Forwarded-ForChain of IP addresses
CF-IPCountryVisitor country code
CF-RayUnique request identifier
CF-VisitorJSON with scheme (http or https)

Your origin server must read the real IP from CF-Connecting-IP instead of the connection source.

Step 4.1: Configure Nginx for Real IP Restoration

Edit your Nginx configuration:

sudo nano /etc/nginx/nginx.conf

In the http block, add:

# Cloudflare IP ranges - restore real visitor IPs
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;

real_ip_header CF-Connecting-IP;

These are Cloudflare’s published IP ranges. Update them periodically as Cloudflare occasionally adds new ranges.

Reload Nginx:

sudo nginx -t
sudo systemctl reload nginx

Verify real IPs appear in the access log after your next visitor:

sudo tail -10 /var/log/nginx/access.log

Real visitor IPs should now appear instead of Cloudflare IPs.

Step 4.2: Configure WordPress for Real IPs

WordPress also needs to know about the forwarded IP. Add to wp-config.php:

/* Trust Cloudflare IP forwarding */
if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
    $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
}

Install and activate the Cloudflare WordPress plugin. It handles IP restoration, cache purging integration, and more.

Phase 5: Cache Configuration

This phase determines what Cloudflare caches and for how long. Wrong cache rules mean either no performance benefit or cached versions of pages that should be dynamic.

What Should Be Cached

Content that is the same for every visitor and changes rarely:

  • Images (JPG, PNG, GIF, WebP, SVG, ICO)
  • CSS files
  • JavaScript files
  • Web fonts (WOFF, WOFF2, TTF)
  • PDF files
  • Static HTML (if your site is static)

What Must Not Be Cached

Content that varies per visitor or changes on every request:

  • WordPress admin (/wp-admin/)
  • WordPress login page (/wp-login.php)
  • WordPress API endpoints (/wp-json/)
  • WooCommerce cart page
  • WooCommerce checkout page
  • WooCommerce account pages
  • Personalised pages for logged-in users
  • Search results (variable per query)

Step 5.1: Configure Caching Level

In Cloudflare dashboard:

  1. Go to Caching
  2. Click Configuration
  3. Set Caching Level to Standard

Standard caches all static resources and respects your origin server’s Cache-Control headers.

Step 5.2: Set Browser Cache TTL

Still in Configuration:

Set Browser Cache TTL to 1 year.

This tells browsers to cache Cloudflare-delivered assets locally for one year. Visitors returning to your site load these assets from their browser cache without any network request at all.

Your origin server or cache-busting plugin handles invalidating this cache when assets change (typically by including a version hash in the filename).

Step 5.3: Create Cache Rules for WordPress

Cache rules control what Cloudflare caches at the edge. The rules below cover the standard WordPress configuration.

In Cloudflare dashboard:

  1. Go to Rules
  2. Click Cache Rules
  3. Create a new rule

Rule 1: Bypass cache for WordPress admin

Name: Bypass WordPress Admin

When:

  • URL path contains /wp-admin
  • OR URL path contains /wp-login.php
  • OR URL contains ?wc-ajax
  • OR Cookie name contains wordpress_logged_in
  • OR Cookie name contains woocommerce_cart_hash
  • OR Cookie name contains woocommerce_items_in_cart
  • OR Cookie name contains wc_session

Then:

  • Set Cache Status to Bypass

This single rule ensures logged-in users, admin pages, and WooCommerce sessions never hit the cache.

Rule 2: Cache static assets aggressively

Name: Cache Static Assets

When:

  • File extension equals jpg, jpeg, png, gif, webp, svg, ico, css, js, woff, woff2, ttf, pdf

Then:

  • Set Edge Cache TTL to 1 month
  • Set Browser Cache TTL to 1 year

Rule 3: Set edge cache TTL for HTML pages

Name: Cache HTML Pages

When:

  • URL path does not contain /wp-admin
  • AND URL does not contain /wp-login.php
  • AND Cookie name does not contain wordpress_logged_in
  • AND Cookie name does not contain woocommerce

Then:

  • Set Edge Cache TTL to 2 hours (adjust based on how frequently your content changes)
Cloudflare cache decision flowchart infographic
How Cloudflare decides what to cache

Step 5.4: Understand Cache Status Headers

After configuring cache rules, verify they work by checking the response headers:

curl -I https://yourdomain.com/wp-content/themes/yourtheme/style.css

Look for the CF-Cache-Status header in the output:

CF-Cache-Status ValueMeaning
HITServed from Cloudflare cache. Origin not contacted
MISSNot in cache. Fetched from origin. Will be cached
BYPASSCache intentionally bypassed (matched a bypass rule)
EXPIREDWas in cache but TTL expired. Refreshed from origin
DYNAMICCloudflare never caches this content type
REVALIDATEDCached but revalidated with origin

Your static assets should show HIT on the second request. Your admin pages should show BYPASS. Your logged-in user pages should show BYPASS.

If static assets show DYNAMIC, Cloudflare is not caching them. Check your cache rules and caching level settings.

Phase 6: Origin Server Lockdown

This is the security step most tutorials skip.

Right now, anyone who knows your origin server IP address can bypass Cloudflare entirely. They connect directly to your server, bypassing DDoS protection, WAF, and your SSL configuration. Your site’s security depends on hiding the origin IP.

But even if your IP becomes known, you can lock the origin server to accept connections only from Cloudflare IP ranges.

Step 6.1: Configure UFW to Allow Only Cloudflare IPs

Remove the current broad HTTP/HTTPS rules:

sudo ufw delete allow 80
sudo ufw delete allow 443

Add rules for Cloudflare IPv4 ranges only:

for ip in \
  173.245.48.0/20 \
  103.21.244.0/22 \
  103.22.200.0/22 \
  103.31.4.0/22 \
  141.101.64.0/18 \
  108.162.192.0/18 \
  190.93.240.0/20 \
  188.114.96.0/20 \
  197.234.240.0/22 \
  198.41.128.0/17 \
  162.158.0.0/15 \
  104.16.0.0/13 \
  104.24.0.0/14 \
  172.64.0.0/13 \
  131.0.72.0/22; do
    sudo ufw allow proto tcp from $ip to any port 80,443
done

Also allow your own IP for direct server management:

sudo ufw allow from YOUR.OWN.IP.ADDRESS

Apply changes:

sudo ufw reload

Verify:

sudo ufw status numbered

Your server now refuses HTTP/HTTPS connections from any IP that is not a Cloudflare range or your own IP. Direct attacks on your origin IP fail at the firewall level.

Step 6.2: Configure Cloudflare Authenticated Origin Pulls

Authenticated Origin Pulls adds a client certificate to Cloudflare’s requests to your origin server. Your origin verifies this certificate and rejects requests that do not have it. This ensures only legitimate Cloudflare traffic reaches your origin even if someone spoofs a Cloudflare IP.

In Cloudflare dashboard:

  1. Go to SSL/TLS
  2. Click Origin Server
  3. Enable Authenticated Origin Pulls
  4. Download the Cloudflare CA certificate from the same page

Save the CA certificate to your server:

sudo nano /etc/ssl/cloudflare-origin-pull-ca.pem

Paste the certificate content. Save.

Update your Nginx server block to require this certificate:

ssl_client_certificate /etc/ssl/cloudflare-origin-pull-ca.pem;
ssl_verify_client on;

Test and reload Nginx:

sudo nginx -t
sudo systemctl reload nginx

Now requests to your origin server without the Cloudflare client certificate receive a 400 Bad Request response. The origin is locked to Cloudflare only.

Phase 7: Performance Settings

Step 7.1: Enable HTTP/3 (QUIC)

HTTP/3 uses UDP instead of TCP. It handles packet loss better and establishes connections faster. Enable it in Cloudflare:

  1. Go to Network
  2. Enable HTTP/3 (with QUIC)

Your origin server does not need to support HTTP/3. Cloudflare terminates HTTP/3 at the edge and connects to your origin over HTTP/2.

Step 7.2: Enable Brotli Compression

Brotli compresses text content more efficiently than gzip. Enable it in Cloudflare:

  1. Go to Speed
  2. Click Optimization
  3. Enable Brotli

Your origin server sends uncompressed responses to Cloudflare. Cloudflare compresses them with Brotli before sending to the visitor. This is handled transparently.

Step 7.3: Enable Minification

Cloudflare can minify JavaScript, CSS, and HTML on the fly without modifying your source files.

  1. Go to Speed
  2. Click Optimization
  3. Under Auto Minify, enable JavaScript, CSS, and HTML

For WordPress sites: if you already use a plugin that minifies (WP Rocket, LiteSpeed Cache), turn off Cloudflare’s minification to avoid double-processing. Use one or the other, not both.

Step 7.4: Configure Polish (Image Optimisation)

Available on Cloudflare Pro and above:

  1. Go to Speed
  2. Click Optimization
  3. Set Polish to Lossless or Lossy depending on your image quality requirements

Polish converts images to WebP for browsers that support it and compresses them without you changing anything on the origin.

Phase 8: Security Settings

Step 8.1: Set Security Level

In Cloudflare dashboard:

  1. Go to Security
  2. Click Settings
  3. Set Security Level to Medium

Medium blocks requests with known malicious patterns. Essentially No Threats is too permissive. High generates too many false positives. Medium is the right production starting point.

Step 8.2: Enable Bot Fight Mode

  1. Go to Security
  2. Click Bots
  3. Enable Bot Fight Mode

This blocks simple bots that do not follow standard bot protocols. Malicious crawlers, scraping bots, and credential stuffers get blocked at the edge.

Step 8.3: Configure WAF Rules for WordPress

The Cloudflare WAF (Web Application Firewall) has pre-built rulesets for WordPress. Enable them:

  1. Go to Security
  2. Click WAF
  3. Click Managed Rulesets
  4. Enable Cloudflare Managed Ruleset
  5. Enable Cloudflare OWASP Core Ruleset

For the WordPress-specific ruleset (free tier):

Create a WAF custom rule blocking common WordPress attacks:

  1. Go to Security, WAF, Custom Rules
  2. Create a rule
Rule name: Block wp-xmlrpc.php
Expression: http.request.uri.path eq "/xmlrpc.php"
Action: Block

This blocks XML-RPC abuse, a common WordPress attack vector.

The DDoS protection article covers what CDN-level protection actually stops and what requires additional configuration.

Phase 9: WordPress-Specific Integration

Step 9.1: Install the Cloudflare WordPress Plugin

The official Cloudflare plugin automatically:

  • Purges Cloudflare cache when you publish or update content
  • Configures Automatic Platform Optimisation (APO) if enabled
  • Provides real-time analytics in WordPress admin
  • Handles IP restoration

Install from WordPress admin: Plugins, Add New, search Cloudflare, install and activate.

In the plugin settings, authenticate with your Cloudflare API key (found in your Cloudflare profile).

Step 9.2: Configure Cache Purging on Publish

Without cache purging, your CDN serves stale content after you publish new posts or update existing ones. Visitors do not see your changes until the CDN cache expires.

The Cloudflare plugin handles this automatically once authenticated. Verify it works:

  1. Publish a test post
  2. Immediately visit that post URL in a private browser window
  3. Check the CF-Cache-Status header using browser developer tools
  4. The header should show BYPASS or MISS on first load, then HIT on the second

Step 9.3: Configure Automatic Platform Optimisation (APO)

APO (available on Cloudflare Pro or as an add-on) caches WordPress HTML pages at the Cloudflare edge, not just static assets.

With APO enabled, Cloudflare serves the entire WordPress page from edge cache. The origin server is not contacted for most page views. For a site with 50,000 monthly visitors, this can reduce origin server load by 80% or more.

APO automatically handles:

  • Cache bypass for logged-in users
  • Cache bypass for WooCommerce sessions
  • Cache invalidation on publish

Enable APO in the Cloudflare plugin settings after purchasing it in your Cloudflare dashboard.

Step 9.4: Configure WP Rocket for Cloudflare

If you use WP Rocket instead of or alongside the Cloudflare plugin:

  1. Go to WP Rocket, CDN settings
  2. Enable CDN
  3. Enter your CDN CNAME (your Cloudflare-proxied domain or a custom CDN subdomain)

WP Rocket rewrite links to point assets to the CDN URL and triggers Cloudflare cache purges on content updates.

Phase 10: Testing the Complete Setup

Do not consider the configuration done until every test passes.

Test 1: Verify CDN is Active

curl -I https://yourdomain.com/

Look for:

  • CF-Ray: header (confirms Cloudflare is proxying)
  • server: cloudflare header
  • CF-Cache-Status: header

Test 2: Verify SSL is Full (Strict)

Open your browser developer tools. Go to Security tab. Check that the certificate is issued to your domain and is trusted.

Also test with:

openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -subject -dates

The certificate should be your origin certificate (Cloudflare Origin Certificate or Let’s Encrypt), not Cloudflare’s edge certificate.

Test 3: Verify Cache Behaviour

Test a static asset — it should be cached:

curl -I https://yourdomain.com/wp-content/themes/yourtheme/style.css

Expected: CF-Cache-Status: HIT (on second request)

Test the admin page — it should be bypassed:

curl -I https://yourdomain.com/wp-admin/

Expected: CF-Cache-Status: BYPASS

Test 4: Verify Real IP Restoration

After a real visitor loads the page, check the Nginx access log:

sudo tail -5 /var/log/nginx/access.log

The IP address should be a real visitor IP, not a Cloudflare IP like 103.21.244.x.

Compare the logged IP against the Cloudflare IP ranges list. If it matches Cloudflare ranges, real IP restoration is not working.

Test 5: Verify Origin Lockdown

Try to access your site directly via the origin IP:

curl -I http://YOUR.ORIGIN.IP/ -H "Host: yourdomain.com"

Expected: Connection refused (if UFW is blocking it)

If you get a response, the origin is accessible without going through Cloudflare.

Test 6: Performance Comparison

Run the curl timing test before and after CDN setup:

curl -w "DNS: %{time_namelookup}s | Connect: %{time_connect}s | TTFB: %{time_starttransfer}s | Total: %{time_total}s\n" \
  -o /dev/null -s https://yourdomain.com/

For a cache HIT from a nearby CDN edge, expect TTFB under 50ms. For an origin request, expect whatever your origin server delivers (typically 150-400ms for a well-configured cloud VPS).

The performance guide covers how TTFB and CDN caching affect real visitor experience and search rankings.

Phase 11: Common Mistakes and How to Avoid Them

MistakeConsequenceFix
Using Flexible SSLData unencrypted between CDN and originSwitch to Full (Strict). Install origin certificate
No cache bypass for wp-adminAdmin users see cached stale pagesAdd cookie-based bypass rule for wordpress_logged_in
No cache bypass for WooCommerceCart contents shared between visitorsAdd bypass rules for woocommerce cookies
Not restoring real IPsWrong IPs in logs. GeoIP broken. Security plugins malfunctionConfigure set_real_ip_from in Nginx
No origin lockdownAttackers bypass CDN by hitting origin IP directlyRestrict port 80/443 to Cloudflare IP ranges only
Double minificationBroken JavaScript or CSSUse only one minification source: plugin or CDN
Caching POST requestsForm submissions return cached responsesEnsure POST requests are not cached (they should not be by default)
Setting Max-Age without EtagStale content served until TTL expiresLet cache-busting tools manage asset versioning
Not purging cache after deploymentsVisitors see old CSS/JS after plugin updatesPurge Cloudflare cache after every code deployment
Enabling HSTS before confirming HTTPS worksSite becomes inaccessible if SSL breaksEnable HSTS only after confirming Full (Strict) works

Frequently Asked Questions

Why is Flexible SSL so bad if visitors still see HTTPS?

Flexible SSL means the connection from Cloudflare to your origin server uses plain HTTP. Traffic between the CDN edge and your server is unencrypted. An attacker between Cloudflare and your server sees login credentials, form submissions, and session cookies in plain text. Your visitors see HTTPS in the browser and assume their data is safe. It is not. Always use Full (Strict) to encrypt the entire path.

Will the CDN break my WordPress site?

A correctly configured CDN should not break anything. The most common cause of CDN-related WordPress breakage is caching pages that should not be cached. If logged-in users see the wrong content, or admin pages show stale data, your cache bypass rules are incomplete. Add bypass rules for the wordpress_logged_in cookie and verify they are working with the CF-Cache-Status header check.

How often should I purge the CDN cache?

Purging happens automatically through the Cloudflare plugin when you publish or update WordPress content. You should manually purge when you update a plugin or theme that changes CSS or JavaScript files, after editing the Nginx or origin server configuration, and after migrating or changing hosting. You should NOT need to purge manually on a regular schedule. If you do, your cache TTL settings are probably too long for how frequently your content changes.

Does a CDN affect SEO?

Positively, when configured correctly. Google uses page speed as a ranking signal. CDN improves TTFB for visitors far from your origin server, which improves Core Web Vitals scores. Google’s crawlers are based in the United States, so they may not benefit as much from a CDN as international visitors do. The CDN also provides DDoS protection, which reduces downtime — and downtime is genuinely harmful to SEO.

Should I use Cloudflare on a managed WordPress host that already has a CDN?

Check what your managed host provides before adding Cloudflare. Kinsta includes a CDN built into their platform. Rocket.net includes Cloudflare Enterprise. Adding Cloudflare in front of a host that already has CDN either doubles the CDN layer (unnecessary) or provides additional features. If your managed host CDN lacks DDoS protection or WAF, adding Cloudflare in front makes sense. If it already includes those features, the benefit is smaller.

How do I debug a 525 SSL Handshake Failed error?

Error 525 from Cloudflare means the SSL handshake between Cloudflare and your origin server failed. Common causes: the SSL certificate on your origin has expired, you are using a self-signed certificate with Full (Strict) mode (which requires a valid certificate), or Nginx is not configured to listen on port 443. Check the origin certificate expiry date: openssl x509 -enddate -noout -in /path/to/cert.pem. Check that Nginx is listening on 443: sudo ss -tlnp | grep nginx. Check the Nginx error log for SSL-related messages.

About The Author

Hostinger

4.7/5 (62k)
Claim 88% OFF Now

Liquid Web

4.3/5 (2.6k)
Claim 50% OFF Now

WP Engine

4.3/5 (1.6k)
Claim 33% OFF Now