Cart
Net 9 regions NRT 232 ms SYD 264 ms AMS 12 ms Uptime 30d 99.997 %
All posts

Guides

The complete guide to CDN cache tuning for WordPress

Omega Digital 11 min read

Most WordPress sites behind a CDN run at roughly a 30% hit ratio because the defaults are too cautious. This is the tuning we walk customers through: cache headers, cache-key normalization, bypass rules, and stale-while-revalidate.

WordPress powers roughly 43% of the web, and the majority of those sites are under-cached. The default configuration, whether you're using a managed host or a DIY stack, typically sends `Cache-Control: no-cache, must-revalidate` for most dynamic routes. That's a reasonable safe default, but it means your CDN is acting as an expensive reverse proxy rather than a distributed cache.

Understanding WordPress cache headers

Before touching CDN configuration, you need to understand what WordPress itself sends. Install a fresh WordPress site and inspect the response headers on a blog post. You'll likely see `Cache-Control: no-cache, must-revalidate, max-age=0`. This comes from WordPress core itself, specifically from `wp_headers()`. The reasoning is sensible for logged-in users (you don't want to serve a cached admin bar to the wrong person) but it's overkill for anonymous visitors.

nginx
# Nginx: override Cache-Control for anonymous traffic
map $http_cookie $cache_bypass {
    default     0;
    ~wordpress_logged_in  1;
    ~wp_postpass          1;
    ~woocommerce_cart     1;
}

server {
    location / {
        if ($cache_bypass = 0) {
            add_header Cache-Control "public, max-age=300, stale-while-revalidate=86400";
        }
        proxy_pass http://wordpress_upstream;
    }
}

Cache-key normalization

The single biggest lever for improving cache hit ratio is cache-key normalization. By default, most CDNs treat `example.com/post/?utm_source=twitter` and `example.com/post/` as different cache entries. UTM parameters, session tokens, and tracking pixels can fragment your cache into thousands of near-identical entries, each with a 0% hit rate.

The fix is to strip query parameters that don't affect page content from the cache key. Most CDNs call this 'query string normalization' or 'cache key rules'. At Omega Digital, you configure this in the CDN settings panel under Cache > Key Rules.

json
{
  "cache_key_rules": [
    {
      "match": "*.example.com",
      "strip_query_params": [
        "utm_source", "utm_medium", "utm_campaign",
        "utm_term", "utm_content", "fbclid",
        "gclid", "mc_eid", "_ga"
      ]
    }
  ]
}

Bypass rules: what must never be cached

  • · `/wp-admin/*`: always bypass, always
  • · `/wp-login.php`: bypass
  • · `/wp-cron.php`: bypass
  • · Any request with a `wordpress_logged_in_*` cookie
  • · Any request with a `woocommerce_*` cookie (cart, checkout, session)
  • · POST requests: always bypass
  • · `/feed/*`: optional, but recommended to cache with short TTL (5 min)

stale-while-revalidate: the secret weapon

The `stale-while-revalidate` directive allows a CDN to serve a stale cached response while simultaneously fetching a fresh copy in the background. For a WordPress blog where content changes infrequently, setting `max-age=300, stale-while-revalidate=86400` means: serve from cache for 5 minutes, then for the next 24 hours serve stale content immediately while refreshing in the background. Your visitors never wait for origin; they just occasionally get content that's a few minutes old.

A cache miss is a tax on every user who triggers it. stale-while-revalidate makes that tax invisible.

WooCommerce: special handling

WooCommerce complicates everything. Cart state is per-user, stock levels change, and personalized pricing is common. The general rule: cache product listing pages aggressively (they change rarely), never cache cart/checkout/account pages, and use ESI (Edge Side Includes) or fragment caching for the mini-cart widget if your CDN supports it.

Measuring your cache ratio

Your target cache hit ratio for a typical WordPress blog should be 85–95% for HTML and effectively 100% for static assets. Check your CDN analytics dashboard: Omega Digital CDN shows HIT/MISS/BYPASS ratios per path pattern. If you're below 70% on HTML, the most likely culprits are missing bypass rules creating cookie-based fragmentation, or no max-age headers being sent from origin.

bash
# Check what cache headers origin is actually sending
curl -sI https://yoursite.com/2026/01/sample-post/ \
  | grep -i 'cache-control\|x-cache\|age\|cf-cache'

The checklist

  • · Override Cache-Control for anonymous users at Nginx/Apache level
  • · Normalize query string: strip UTM and tracking params
  • · Configure bypass rules for wp-admin, logged-in cookies, WooCommerce cookies
  • · Set stale-while-revalidate on HTML responses
  • · Verify static assets have long TTLs (1 year with cache-busting filenames)
  • · Monitor HIT ratio weekly and set an alert if it drops below 80%
OD

Omega Digital

Platform · Omega Digital