All posts
devops

Cloudflare for WordPress: full performance and security optimization

How to configure Cloudflare (Free/Pro) for WordPress step by step: cache, APO, WAF, Bot Fight Mode, page rules, CDN. Real measurement results and configuration for Poland.

8 min readUpdated: June 27, 2026

Cloudflare for WordPress: full optimization

Cloudflare is the best free thing you can do for your WordPress. For 90% of sites the Free plan is enough β€” it gives CDN, cache, SSL, basic WAF. This post shows the full configuration I use at every client.

What Cloudflare gives you for free

| Feature | Free plan | Pro plan ($20/m) | |---------|-----------|------------------| | CDN (static asset cache) | βœ… | βœ… | | Universal SSL | βœ… | βœ… | | Basic WAF (3 rules) | βœ… | βœ… | | Rate limiting (1 rule) | βœ… | 5 rules | | DDoS protection (L3/L4) | βœ… | βœ… | | Bot Fight Mode | βœ… | βœ… advanced | | Page Rules | 3 | 20 | | Workers (serverless) | 100k/day | 10M/day | | APO (HTML cache) | ❌ ($5/m) | βœ… in Pro price | | Image Resizing | ❌ | βœ… | | Web Analytics | ❌ | βœ… |

My recommendation: for blogs and small sites β€” Free + APO ($5/m) for $5/month total. For e-commerce and SaaS β€” Pro ($20/m).

Step 1: Add the site to Cloudflare

# 1. Create an account on cloudflare.com
# 2. Add the domain β†’ Cloudflare scans DNS records
# 3. Change nameservers at the registrar (OVH, namecheap) to:
#    ada.ns.cloudflare.com
#    bob.ns.cloudflare.com
#    (Cloudflare gives you the right ones)
# 4. Wait 24-48h for DNS propagation

After propagation all traffic goes through Cloudflare. Your server (origin) is no longer directly visible from the internet β€” attackers see only Cloudflare IPs. That alone is basic DDoS protection.

Step 2: SSL/TLS

Crypto β†’ SSL/TLS set to Full (strict). This enforces end-to-end HTTPS (Cloudflare ↔ origin) with certificate validation.

SSL/TLS β†’ Overview β†’ Full (strict)

Why not "Flexible"? Flexible encrypts only Cloudflare ↔ user, but Cloudflare ↔ origin goes over HTTP. Someone on the origin provider network could sniff it.

On the origin server you need a valid SSL certificate. The easiest: Let's Encrypt via Certbot:

# On the origin server
sudo apt install certbot python3-certbot-apache  # for Apache
# or
sudo apt install certbot python3-certbot-nginx  # for Nginx

sudo certbot --nginx -d example.com -d www.example.com
# or
sudo certbot --apache -d example.com -d www.example.com

Certbot auto-renews the certificate every 60 days.

Step 3: Cache configuration

Caching β†’ Configuration:

Caching Level: Standard
Browser Cache TTL: 4 hours
Crawler Hints: ON
Always Online: ON

Standard cache level caches everything possible except dynamic endpoints. For WP without APO this caches CSS, JS, images, fonts β€” i.e. 80% of requests.

Page Rules (free: 3 rules)

Page Rules are the most powerful feature of the free plan. Three rules that give the most:

# Rule 1: Bypass cache for logged-in users
URL: *example.com/wp-admin*
Cache Level: Bypass
Security Level: High

# Rule 2: Cache HTML for posts (24h)
URL: *example.com/*
Cache Level: Cache Everything
Edge Cache TTL: 1 day
Browser Cache TTL: 4 hours

Cache Everything caches HTML on the Cloudflare edge. Without APO this works only when Cloudflare sees cache-control headers from origin. WordPress does not send them by default β€” you need the Cloudflare plugin (official) or WP Super Cache.

Cloudflare plugin for WordPress

# Install the official Cloudflare plugin
wp plugin install cloudflare --activate

# Enable automatic cache purge on update
# Set the API token in plugin settings

The plugin also adds auto-purge cache on post publish. Without it you have to click "Purge Cache" manually in Cloudflare after every update.

Step 4: Performance optimizations

Speed β†’ Optimization:

Auto Minify: HTML, CSS, JS (βœ“)
Brotli: ON
Early Hints: ON
Rocket Loader: ON (test, sometimes breaks JS)

Auto Minify compresses CSS/JS/HTML on the fly. For most sites that's a 10-20% size reduction. Exception: sites with inline critical CSS β€” minify can break ordering.

Brotli is modern compression (better than gzip). Supported by 95% of browsers. Gives 15-20% smaller transfers than gzip.

Rocket Loader loads JS asynchronously. For simple sites it speeds up rendering. For complex applications (WooCommerce with lots of JS) it can cause errors β€” test.

Step 5: Security (WAF + Bot Fight Mode)

Security β†’ WAF β†’ Managed Rules: enable Cloudflare Managed Ruleset. A free set of rules protecting against known attacks (SQL injection, XSS, PHP exploits). Zero configuration, zero false positives on a typical WP site.

Security β†’ Bots β†’ Bot Fight Mode: enable.

Security β†’ Settings β†’ Challenge Passage: 30 minutes.

Three custom WAF rules I add

# Rule 1: Block XML-RPC (commonly attacked)
Expression: http.request.uri.path contains "/xmlrpc.php"
Action: Block

# Rule 2: Protect wp-login (rate limit)
Expression: http.request.uri.path contains "/wp-login.php"
Rate limit: 5 requests per 10 seconds
Action: Managed Challenge

# Rule 3: Block scanner User-Agents
Expression: 
  (http.user_agent contains "nikto") or
  (http.user_agent contains "sqlmap") or
  (http.user_agent contains "masscan")
Action: Block

XML-RPC is an old WP protocol (the equivalent of SOAP), today practically unnecessary, but bots attack it because /xmlrpc.php has simple "check if the password is correct" methods. Blocking it = zero brute-force attempts on that endpoint.

Step 6: APO (HTML cache) - optional $5/m

APO is the most important optimization for WP. It caches HTML on the Cloudflare edge. Without APO HTML is generated by origin (PHP + MySQL) on every request. With APO β€” HTML flies from the nearest Cloudflare edge node.

Enabling APO:

  1. Cloudflare Dashboard β†’ Speed β†’ Optimization β†’ APO
  2. Enable (costs $5/m/site for Free plan, free in Pro)
  3. Install the Cloudflare plugin in WP, give it the API token
  4. Enable "Auto-Purge on Update" in the plugin

Real results (from my last 8 projects):

| Metric | Without APO | With APO | |--------|-------------|----------| | TTFB (cache miss) | 600-1200ms | 400-800ms (origin) | | TTFB (cache hit) | 400-600ms | 30-80ms | | LCP (Largest Contentful Paint) | 2.5-4.0s | 1.2-2.0s | | Load time (P75) | 4.5-6.0s | 1.5-2.5s | | Traffic to origin | 100% | 5-15% |

These are numbers I have seen, not marketing promises. For sites with >5k page views/day APO pays back in a week (less traffic to the server = cheaper hosting).

Step 7: Rate Limiting

Security β†’ WAF β†’ Rate Limit Rules (free plan: 1 rule):

URL: *example.com/wp-login.php
Rate: 5 requests per 10 seconds
Action: Block for 600 seconds

This protects against brute-force password attacks. Without it a bot tries 1000 password combinations per second from one IP.

For the Pro plan you have 5 rules. My typical configuration:

  1. /wp-login.php β€” 5 req/10s
  2. /wp-admin/admin-ajax.php β€” 20 req/10s (for AJAX)
  3. /wp-json/* β€” 30 req/10s (for REST API)
  4. Global β€” 200 req/10s per IP (prevention)

Step 8: DNS β€” do not expose the origin IP

Critical mistake: your origin server has an IP. Someone can scan it directly, bypassing Cloudflare. Solution:

  1. Force traffic through Cloudflare: in Cloudflare DNS turn off proxy for A records (orange cloud β†’ grey cloud for the origin). Set origin IP in the server firewall to accept only Cloudflare IPs.

  2. Hide origin IP behind Cloudflare Tunnel (free):

    # On the origin server
    sudo cloudflared service install <tunnel-token>
    
  3. Do not send origin IP in emails (SMTP header leak). Set in wp-config.php:

    // Disable leaky Server header
    header_remove('X-Powered-By');
    header_remove('Server');
    

Step 9: Monitoring and testing

# Check whether traffic goes through Cloudflare
curl -I https://example.com
# Look for: server: cloudflare

# Check cache status
curl -I https://example.com | grep -i cf-cache-status
# HIT / MISS / DYNAMIC / BYPASS / EXPIRED

# Test from different locations (free)
# https://www.webpagetest.org
# https://tools.pingdom.com

# Cloudflare Web Analytics (free for Pro)
# Dashboard β†’ Analytics β†’ Web Analytics

Diagnosing cache miss

When you see a lot of cf-cache-status: DYNAMIC, check:

  • Query string in the URL β€” Cloudflare by default does not cache URLs with ?utm_source=.... A Page Rule with "Ignore Query String" fixes it.
  • WP cookie β€” when a user is logged in, Cloudflare does not cache. For not logged in: it works.
  • Vary header β€” if the origin sends Vary: User-Agent, cache splits into N variants. In WP add Vary: Accept-Encoding instead.

Common configuration mistakes

1. Enabling "Cache Everything" without a Page Rule for wp-admin

Effect: logged-in users see a cached version of the page, nobody can log in. Fix: a Page Rule with "Cache Level: Bypass" for /wp-admin/* and /wp-login.php.

2. Disabling proxy in DNS

When a user turns off the orange cloud (proxy) on the A record, traffic goes directly to origin. Zero protection, zero cache. Always proxy=on for the main domain and subdomains (www, cdn, etc.).

3. No Cloudflare plugin in WP

Without the plugin cache is not cleared after a post update. The user publishes an article, still sees the old version for 24h. Fix: plugin + auto-purge.

What is next

If you want me to set up Cloudflare for you (with Cloudflare Tunnel to hide origin IP, optimal cache and WAF) β€” get in touch. 1-2 days of work, starting from 800 PLN.

Tags:#cloudflare#wordpress#cdn#performance#security

NajczΔ™Ε›ciej zadawane pytania

Is Cloudflare Free enough for WordPress?
For 90% of sites yes: the free plan gives CDN, basic WAF, rate limiting (1 rule), Universal SSL, cache up to 80% of traffic. You need Pro ($20/m) when: you run e-commerce with thousands of products, you need Web Analytics, image resizing, advanced rate limiting, or traffic exceeds 1M page views/month.
What is APO (Automatic Platform Optimization) and is it worth it?
APO is a paid Cloudflare add-on ($5/m/site) that caches HTML at the edge β€” for WP typically enabled via plugin. Without APO: only static assets (CSS, JS, images) are cached, HTML is generated by the server on every request. With APO: TTFB drops from 800ms to 50-100ms for cached pages. ROI: if your site has >5k page views/day, APO pays back within a week.
How does Cloudflare affect SEO?
Positively, if configured well. Cloudflare improves Core Web Vitals (faster LCP, lower TTFB) which is a Google ranking signal. Warning: misconfigured page rules can block Google crawlers β€” always test in Search Console after changes. In my projects average +12% organic traffic after migrating to Cloudflare.
Will Bot Fight Mode block Google crawlers?
No. Bot Fight Mode blocks identified bots (scrapers, hackers), but **not** legitimate crawlers like Googlebot (verified user agent + reverse DNS). If you are paranoid β€” add a WAF rule 'Allow Googlebot'. In practice Bot Fight Mode does not block Googlebot, but enable it gradually and monitor logs.

Related posts