HomeMethod

Knowledge

Web VitalsTechniquesSnippetsAnswersImpactsBottlenecks

Cache Query Strings

Extend page cache coverage to URLs with query string parameters instead of bypassing them.

Overview

Most page caches bypass caching entirely when a URL contains a query string — ?utm_source=newsletter, ?page=2, ?color=red — because query strings might indicate dynamic or user-specific content. In practice, the vast majority of query strings on WordPress sites are tracking parameters (UTM), pagination, or filter values that produce the same HTML for all users. Caching these URLs delivers the same performance gains as page cache while also covering the large share of traffic that arrives via tracked links.

Impact grade, A+ to D: how much of the Lighthouse score this technique can move. Unaffected: TBT, CLS.

The Problem

A marketing campaign sends 10,000 visitors to /landing-page/?utm_source=facebook&utm_campaign=spring. Without query string caching, every single visit bypasses page cache, executes full PHP, and hits the database. The page takes 800 ms to generate instead of 10 ms from cache. The traffic spike — the moment when performance matters most — hits the server completely uncached. Affiliate link traffic, email campaign recipients, and paginated archives all suffer the same fate.

Performance Impact

LCP

High

tracked and paginated URLs serve from cache instead of requiring full PHP execution per visit

FCP

High

campaign traffic and paginated archives all receive full cache-speed responses

SI

Moderate

cached pages render faster and more completely for all query-string-bearing URLs

TTFB

700ms–1.5s

server response drops from full PHP execution time to cached page read time

Risk: Medium

caching pages with user-specific query strings risks serving wrong content — configure exclusions carefully

How it works

  1. 01

    Identify which query strings are safe to cache

    UTM parameters (utm_source, utm_medium, utm_campaign), click IDs (fbclid, gclid, msclkid), and pagination (page, paged) do not affect page content and are safe to cache. Query strings that affect content — WooCommerce filters, search queries, session tokens — should remain uncached.

  2. 02

    Configure the cache to ignore tracking parameters

    Most cache plugins support a list of query string parameters to ignore when building the cache key. Add UTM parameters and click IDs to this list — the cached page for /blog/ is then served for both /blog/ and /blog/?utm_source=email without generating a separate cache entry.

  3. 03

    Create separate cache entries for content-affecting parameters

    For filter parameters that do change content (?color=red&size=L on a WooCommerce shop), create separate cache entries per unique parameter combination. This requires more cache storage but delivers full cache performance for filtered pages.

  4. 04

    Strip irrelevant parameters server-side

    At the Nginx or CDN level, strip known tracking parameters from the cache key while passing them through to the application. This ensures one cache entry per real page while tracking data is still available to analytics.

Code Example

Before
# Default: any query string bypasses page cache
# /landing-page/?utm_source=newsletter → PHP execution on every visit
# /shop/?page=2 → PHP execution on every visit
After
# Nginx: normalize cache key by removing tracking parameters
map $query_string $normalized_query {
    ~*(?:^|&)(?:utm_[^&]*|fbclid=[^&]*|gclid=[^&]*)(?:&|$) "";
    default $query_string;
}
fastcgi_cache_key "$scheme$request_method$host$request_uri";

# WP Rocket / LiteSpeed: add to "Never Cache Parameters" exclusion list:
# utm_source, utm_medium, utm_campaign, utm_term, utm_content, fbclid, gclid, msclkid

In WP Rocket: Settings → Cache → Cache query strings. In W3 Total Cache: Page Cache → Ignored query stems. Add UTM parameters and click IDs to the ignored list, not the excluded list.

Limitations

  • Caching pages with WooCommerce cart or checkout query strings risks serving one user’s cart state to another. Always exclude wc-ajax, add-to-cart, and any authentication-related parameters.
  • The number of cache entries grows with each unique parameter combination that is cached rather than ignored. On a large site with many filter combinations, this can significantly increase cache storage requirements.
  • Cache invalidation becomes more complex when the same content exists under multiple URLs — a post update must invalidate all cached variants of its URL.

Common Mistakes

Caching all query strings without exclusions

Always define an exclusion list for user-specific and security-sensitive parameters before enabling query string caching. Test with a logged-in user adding items to cart to verify personalized content is not cached.

Creating separate cache entries for UTM parameters

UTM parameters do not change page content. Stripping them from the cache key means all tracked traffic hits the same cached page — fewer cache entries, higher cache hit rate, and no stale content risk.

Test this techniqueCache AnalysisRun the tool

Targeted fixes, not guesswork.

Start an Engagement
Support our family now