Take WordPress to the edge with Cloudflare, without writing a plugin
Cache rules, a small Worker and early hints so WordPress serves 90% of requests from the edge — plus the traps that quietly break caching.
- Published
- 10 June 2025
- Read
- 2 min read
- Written by
- SSUSEMAN

Most WordPress sites serve the same pages to almost everyone — yet we re-render them in PHP on every request. Cloudflare fixes that without touching your theme.
Start with your own traffic
Open Analytics and look at which paths consume requests. On my last audit, the top five paths were 78% of all requests, all of them static article pages.
A cache rule that is safe
Cache only GET requests without a login cookie, excluding admin and cart paths:
(http.request.method eq "GET"
and not http.request.uri.path contains "/wp-admin"
and not http.request.uri.path contains "/wp-login"
and not http.request.uri.path contains "/cart"
and not http.cookie contains "wordpress_logged_in"
and not http.cookie contains "woocommerce_cart_hash")
-> Cache eligible, Edge TTL 1 hour, Browser TTL 10 minutes
A small Worker with outsized effect
Three jobs: strip noisy query parameters, add Early Hints, and serve a fallback when the origin is down.
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
['fbclid', 'gclid', 'utm_source', 'utm_medium'].forEach((k) => url.searchParams.delete(k));
const cacheKey = new Request(url.toString(), request);
const cache = caches.default;
let res = await cache.match(cacheKey);
if (res) return res;
res = await fetch(cacheKey, { cf: { cacheEverything: false } });
if (res.ok) {
const headers = new Headers(res.headers);
headers.set('Cache-Control', 'public, max-age=600, s-maxage=3600');
ctx.waitUntil(cache.put(cacheKey, new Response(res.body, { ...res, headers })));
}
return res;
},
};
Early Hints from the origin
If the origin sends Link headers with a 103 Early Hints response, the browser starts fetching CSS and fonts before the HTML arrives. In production this bought 100–300ms of LCP.
Header add Link "</wp-content/themes/suseman/style.css>; rel=preload; as=style"
Header add Link "</fonts/inter-var.woff2>; rel=preload; as=font; crossorigin"
Traps that silently break caching
- Analytics plugin cookies make every request a cache miss. Scope the bypass rule.
- Nonces in HTML: a cached checkout page hands users a stale nonce and the form fails.
- Geo currency needs a Vary header or a country-keyed cache.
- Forgetting to purge tag archives after publishing leaves stale pages for hours.
Always test: check
cf-cache-statuswithcurl -Iwhile logged in and logged out. A HIT on the wrong page means your rule is too loose.
Outcome
On a Thai news site: 91% cache hit rate, 140ms average TTFB, 87% less origin load, and half the server bill.
Written by
SUSEMAN · Infrastructure engineer · Writer
A journal of cloud & web engineering · Bangkok, Thailand
The weekly dispatch
New articles, tools worth testing and lessons from production — every Thursday. No spam, ever.


