Cloudflare's free plan puts an edge with HTTP/3, Brotli, a firewall and free TLS in front of any site, and its dashboard has hundreds of switches. About fifteen of them change what a website report shows. This guide walks through those in the order that avoids breaking the site, says what each does to the findings, and ends with the checks that prove it worked from outside. Allow 45 minutes, including a purge and a re-test.
Quick answer
- DNS record proxied (orange cloud), otherwise nothing below applies.
- SSL/TLS mode Full (strict), never Flexible. Then Always Use HTTPS, Automatic HTTPS Rewrites, Minimum TLS 1.2, TLS 1.3 on, and HSTS once every subdomain works over HTTPS.
- Speed: Brotli on (default), Early Hints on, Rocket Loader off on most WordPress sites. Auto Minify no longer exists.
- Caching: leave the default (static files only). Use a Cache Rule for HTML only when the site has no logged-in visitors or carts, or use APO.
- Security: the free managed WAF ruleset, Bot Fight Mode, one rate-limit rule on the login path, and never a rule that challenges verified bots.
- Security headers: one Transform Rule (Modify Response Header) that sets each header.
- Verify with the security headers checker, the HTTP/2 test and a cold and a warm TTFB measurement.
Why the settings matter
Cloudflare is a proxy. Every visitor request goes to a Cloudflare data centre near them, which either answers from its cache or asks your server (the origin) and relays the answer. That position lets it terminate TLS, speak HTTP/3, compress, add headers and block bots without touching the origin. It also means a wrong setting affects every page at once, and that what your server sends is not necessarily what visitors receive.
Two settings do most of the damage on new setups. Flexible SSL talks plain HTTP to the origin, which produces redirect loops the moment the origin insists on HTTPS and leaves the last hop unencrypted. A "cache everything" rule caches HTML, which is wonderful on a brochure site and serves one shopper's cart to the next on a store. Both take one click to set and a support ticket to diagnose.
The rest are free wins: HTTP/3, Brotli, TLS 1.3, security headers, a firewall and a rate limit each take an afternoon on a server and a minute here, and the report shows every one of them.
How getReport checks it
The report sees Cloudflare from outside, as a visitor does, so it grades Cloudflare and the origin together. The HTTP/2 test makes a TLS handshake offering h2 and http/1.1 and records the protocol and TLS version the edge picks, reads the Alt-Svc header for HTTP/3, and loads the page in Chromium to count the responses per protocol. The CDN finding recognises Cloudflare from the cf-ray header, a server: cloudflare value or cf-cache-status; the Best practices module reads content-encoding on every text response for the compression finding and Cache-Control or Expires on every script, stylesheet, image and font for the cache finding. Security headers are read from the final response, so a header set in a Transform Rule counts exactly like one set on the origin.

The Server header finding passes once the proxy is on, because Cloudflare replaces the origin's Server value with cloudflare, which carries no version. X-Powered-By passes through from the origin unless you remove it with the "Remove X-Powered-By headers" Managed Transform.
Step by step
1. Proxy the DNS record
DNS → Records. The A or CNAME records for the root and www need the orange cloud ("Proxied"). A grey cloud ("DNS only") means Cloudflare answers the DNS query and nothing else: no edge TLS, cache, firewall or HTTP/3, and the report shows whatever the origin does. Subdomains you do not want proxied (mail, FTP) stay grey.
Once proxied, the origin's IP is hidden and every setting below applies.
2. SSL/TLS: Full (strict), then the encryption switches
SSL/TLS → Overview. The modes are Off, Flexible, Full and Full (strict). Flexible serves HTTPS to visitors and fetches from your origin over plain HTTP. If the origin redirects HTTP to HTTPS, as it should, the visitor gets an endless loop: Cloudflare asks over HTTP, the origin says "go to HTTPS", Cloudflare asks over HTTP again. The origin also sees http:// and prints http:// asset URLs, which is mixed content.
Full (strict) encrypts both hops and checks the origin's certificate. The origin needs a valid certificate: a free Let's Encrypt one, or a Cloudflare Origin CA certificate (SSL/TLS → Origin Server → Create Certificate), which browsers would not trust directly but Cloudflare does, and which lasts up to 15 years. Set the mode to Full (strict) and open the site; a 526 error means the origin certificate is invalid, a 525 means the handshake failed.
Then SSL/TLS → Edge Certificates:
- Always Use HTTPS: on. Cloudflare answers every
http://request with a 301 tohttps://at the edge; the report's http-to-https finding passes and the origin never sees plain HTTP. - Automatic HTTPS Rewrites: on. Rewrites
http://asset URLs in the HTML tohttps://when the host is known to support it; a safety net for the mixed-content finding, not a replacement for fixing the URLs. - Minimum TLS Version: 1.2. The report's TLS check makes a deliberate TLS 1.0/1.1 handshake and expects a refusal.
- TLS 1.3: on.
- HSTS: on, after step 3.
3. HSTS, with the warning
HSTS tells browsers to refuse plain HTTP for your domain for max-age seconds. Cloudflare (SSL/TLS → Edge Certificates → HTTP Strict Transport Security) makes you acknowledge a warning first, because the setting is sticky: a browser that has seen the header cannot reach an HTTP-only subdomain until the time runs out, and if you leave Cloudflare the origin must keep serving valid HTTPS.
Enable it with "Max Age" at 6 months, "Apply HSTS policy to subdomains" only when every subdomain (including the grey-cloud ones) answers over HTTPS, and "Preload" only after reading HSTS safely and the preload list. Keep one source: if the origin also sends the header, remove it there.
4. Speed → Optimization
The Content Optimization tab has the three that matter:
- Brotli: on by default. Cloudflare compresses text responses at the edge whether or not the origin did, so the compression finding passes even for an origin with gzip off. The exception is a
Cache-Control: no-transformheader from the origin, which tells Cloudflare not to touch the response. - Early Hints: on. Cloudflare remembers the
Link: rel=preloadandpreconnectheaders your origin sent and replays them as a103response while the origin works, so the browser fetches CSS and fonts earlier. - Rocket Loader: off on WordPress and any site with inline scripts that expect to run in order. It defers every
<script>until after the page, which improves lab scores and breaks sliders, forms and consent banners. If a script breaks after enabling Cloudflare, this is the first suspect.
Auto Minify was removed in 2024; minification belongs in the build step or the caching plugin.
5. Caching
Caching → Configuration. Two settings and one rule:
- Caching Level: Standard. Cloudflare caches static file extensions (images, CSS, JS, fonts), not HTML unless a rule says so.
- Browser Cache TTL: "Respect Existing Headers" when the origin already sends
Cache-Control, as any caching plugin or the configs in Cache-Control for humans do. A value instead overrides the origin, which is the quick fix when the origin sends nothing, and the reason a static file sometimes shows a lifetime the origin never set. The report reads what reaches the browser. - A Cache Rule (Caching → Cache Rules) per path is the modern way to say "cache
/wp-content/uploads/*for a year at the edge and in the browser". Cache Rules set eligibility, edge TTL and browser TTL separately.
The trap is a rule with "Cache everything" or "Eligible for cache" on all paths. Cloudflare then caches HTML, including the HTML it fetched for a logged-in editor or a shopper with a cart, and serves it to the next anonymous visitor. On a brochure site with no logins it is the biggest TTFB win available; on WordPress with users, WooCommerce or any personalised page it needs bypass rules for the cookies (wordpress_logged_in, woocommerce_items_in_cart, wp-postpass) placed above the caching rule, plus a purge after every publish. CDN basics: what it fixes and what it does not covers those rules.
After any deploy, theme change or plugin update: Caching → Configuration → Purge Cache, by URL for one page or "Purge everything" after a redesign. Development Mode bypasses the cache for three hours while you work.
6. Security
Security on the free plan:
- WAF → Managed rules: the Cloudflare Free Managed Ruleset is on by default and blocks widely exploited request patterns. Leave it on.
- Bots → Bot Fight Mode: on. It challenges traffic that Cloudflare classifies as automated and leaves verified bots (Googlebot, Bingbot and the other crawlers Cloudflare validates) alone.
- WAF → Rate limiting rules: the free plan includes a rule with a short window. Spend it on the login path:
(http.request.uri.path eq "/wp-login.php"), a low request count per period, action Block. The bot protection guide has the full rule and thexmlrpc.phpcompanion. - Security Level: Medium. "I'm Under Attack" mode challenges every visitor, including crawlers that cannot solve it; use it during an attack only.
- Challenge Passage: 30 minutes, how long a solved challenge lasts, is fine.
Never write a custom WAF rule that challenges or blocks "all bots". Add and not cf.client.bot to any rule that targets automated traffic so verified crawlers pass, or pages start falling out of Google.
7. Security headers with Transform Rules
Rules → Transform Rules → Modify Response Header → Create rule. One rule, "All incoming requests", with one "Set static" line per header:
Strict-Transport-Security (leave to the HSTS setting in step 3)
Content-Security-Policy default-src 'self'; img-src 'self' data: https:; script-src 'self'; style-src 'self' 'unsafe-inline'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'
X-Content-Type-Options nosniff
X-Frame-Options SAMEORIGIN
Referrer-Policy strict-origin-when-cross-origin
Permissions-Policy camera=(), microphone=(), geolocation=(), payment=()"Set" overwrites a header the origin already sends; "Add" appends a second copy, which is what you do not want for X-Frame-Options. Cloudflare's Managed Transforms toggle ("Add security headers") sets a fixed subset in one click; use one or the other. Start the CSP as Content-Security-Policy-Report-Only and watch the browser console for a week before enforcing.
8. Redirects: Rules, not Page Rules
The older Page Rules (three on the free plan) are being replaced by the newer Rules products. For a www decision use Rules → Redirect Rules with a single dynamic rule: when hostname equals www.example.com, redirect to the expression concat("https://example.com", http.request.uri.path) with status 301 and "Preserve query string" on. Because Always Use HTTPS also redirects at the edge, check that the two do not stack into http://www → https://www → https:// (two hops); the redirect checker shows every hop.
9. APO for WordPress
Automatic Platform Optimization is a paid add-on (a few dollars a month on the free plan) that works with the Cloudflare WordPress plugin. It caches HTML at the edge, purges when you publish, and bypasses the cache for logged-in users and WooCommerce cookies on its own: the "cache everything" rule from step 5 done properly. It is the biggest TTFB improvement for WordPress on modest hosting, and the only paid feature in this guide.
10. What Cloudflare does not fix
The proxy makes bytes arrive faster, not fewer. It cannot fix:
- Origin TTFB on a cache miss. Without HTML caching, every page request still runs your PHP; Cloudflare relays the wait.
- Render-blocking CSS and JavaScript, long tasks, a 2 MB hero image, layout shift. Those happen in the browser or in the theme. (Polish, which compresses and converts images, is on paid plans.)
- Third-party scripts the page loads from other hosts.
If the speed panel still shows LCP over 2.5 s after this guide, the fix is in the page (see Largest Contentful Paint), not in the dashboard.
Verify
- Security headers checker: every header finding passes; the
Serverfinding passes (cloudflare), HSTS shows the max-age you chose. - HTTP/2 test: the protocol table shows h2 negotiated, HTTP/3 advertised via
Alt-Svc, TLS 1.3; the CDN finding names Cloudflare; the compression finding passes; the cache finding lists no static file without a lifetime. - Cold and warm TTFB. The first request after a purge is a cache miss and measures the origin; the next is what visitors get. Run the TTFB test right after the purge, then Re-run from the full report for the warm figure. For an immediate pair, run
curl -so /dev/null -w "%{time_starttransfer}\n" https://example.com/twice.curl -sI https://example.com/ | grep -i cf-cache-statusshowsHITon a cached file andDYNAMICon HTML that is not cached (the default). - The site still works: log in, add to cart, submit a form, in a private window with the cache warm.
Common mistakes
- Flexible SSL. Symptom: "too many redirects" or mixed-content warnings the moment the origin enforces HTTPS. Fix: an origin certificate and Full (strict).
- Cache everything on a dynamic site. Symptom: visitors see someone else's cart or the admin bar; edits do not show until a purge. Fix: bypass rules for the login and cart cookies above the cache rule, or APO, or no HTML caching at all.
- Rocket Loader breaking scripts. Symptom: a slider, form or consent banner fails only through Cloudflare. Fix: turn it off.
- Challenging all bots. Symptom: pages drop from Google; Search Console reports "blocked" fetches. Fix: exclude
cf.client.bot, keep Security Level at Medium, and never leave "I'm Under Attack" on. - Forgetting to purge after a deploy. Symptom: old CSS with the new HTML for hours. Fix: purge in the dashboard or from the caching plugin; add it to the deploy checklist.
- A DNS-only record for the host that matters. Symptom: the report shows the origin's
Serverheader, no HTTP/3 and no CDN despite "having Cloudflare". Fix: orange cloud on the root andwww.