Check which caching layer is hitting your WooCommerce cart and checkout pages
Published 4 min read
When a caching layer serves a stale cart page, the buyer sees someone else's session. The symptoms are specific: a cart showing items the visitor never added, a coupon that refuses to apply even with a valid code, a 'session expired' message on a page loaded for the first time. These rarely appear while testing alone on a site with nothing cached. They appear in production, under load, on the checkout pages that matter most.
The fix is an exclusion rule in the right place. The diagnostic step is knowing which caching layer needs the rule. A caching plugin, a reverse proxy running at the host level and a CDN all maintain their own cache, and each has its own configuration. Reading the response headers from the cart and checkout pages identifies which one is responsible.
Why a cookie-based exclusion still misses fresh buyers
Most caching plugins offer two exclusion methods for WooCommerce: by URL pattern and by cookie. The cookie path watches for woocommerce_items_in_cart or the WooCommerce session cookie and skips the cache when either is present. It works correctly for a returning buyer who already has something in their cart.
A new visitor has no cart cookie yet. Their first request to /cart/ or /checkout/ arrives with nothing that triggers the bypass, and the caching layer can serve them a cached copy. The page appears to load, but the session it reflects belongs to whoever generated the cached response last. URL-based exclusion covers this case; cookie-based exclusion alone does not.
Host-level caches that sit outside WordPress entirely
Managed WordPress hosts commonly run a caching layer between the visitor and PHP: Nginx proxy_cache, Varnish, LiteSpeed's built-in cache, or a proprietary system. This layer is not a WordPress plugin. Clearing the cache from the WordPress dashboard, or configuring your caching plugin's exclusion list, does not reach it.
The tell is that clearing every WordPress-level cache still results in cached responses on cart or checkout pages. The host-level cache has its own exclusion configuration, usually in the hosting control panel or the host's own caching plugin, and it needs its own exclusion rule for WooCommerce's key pages.
The response headers that name the responsible layer
Every caching layer that hits a request leaves a header in the response. X-Cache: HIT means a cache served this response rather than PHP. CF-Cache-Status: HIT means the response came from Cloudflare's edge. An Age header with a value above zero names how many seconds old the cached copy is. X-Varnish with two numbers means Varnish is in the stack and the second number is the cache hit ID. LiteSpeed adds X-LiteSpeed-Cache: hit.
The plugin runs wp_remote_get() against the cart, checkout and my-account URLs without passing any WordPress authentication cookies. The response headers from those requests appear in a table: page name, URL, a cached or not-cached status, and the specific headers that produced it. A clean result means the response arrived with no cache indicators. A flagged result names the header and its value, which points directly at the layer that needs the exclusion rule.
What you get
Included
- Response header check for cart, checkout and my-account pages as an anonymous visitor sees them
- Detection of server-level, proxy-level and CDN-level cache hits from a single admin screen
- Per-page status table showing which headers triggered a cached result
Not included
- Configuring any caching plugin's exclusion list, which depends on which plugin and host you have
- Checking browser-level caching behavior, which requires browser DevTools rather than server-side inspection
- Requests made with a logged-in session or an active cart cookie
- Automated monitoring that runs the check on a schedule before each sale
- Clearing cache from any layer directly
Questions
Does passing the check mean the exclusion in my caching plugin is working?
If no cache headers appear in the results, the pages are being served fresh from whatever layer handles the request. That said, the check is a snapshot: it makes one request per page at one moment. If your site gets enough traffic to warm the cache between checks, a later request might show different results. Running the check a few minutes apart confirms whether the exclusion is holding consistently.
Build it in Steem
The button opens the builder with this guide's prompt filled in, so you can change anything before it runs. Nothing is built, and nothing is charged, until you send it.
Read the prompt (149 words)
Build a WordPress plugin called WooCommerce Cache Checker. Add a Cache Check tab to WooCommerce > Status. The tab lists three pages: Cart (wc_get_cart_url()), Checkout (wc_get_checkout_url()) and My Account (wc_get_account_page_url()). For each page, make an HTTP GET request using wp_remote_get() with no authentication cookies set. Read the response headers and render a table with four columns: Page, URL, Status (Cached or Not cached), and Headers. Mark a page as Cached if the response contains X-Cache: HIT, CF-Cache-Status: HIT, Age above zero, or X-LiteSpeed-Cache: hit. Show the specific header name and value in the Headers column. If any page is marked Cached, display a WooCommerce admin notice at the top of the tab explaining that at least one page may be served from cache. Add a Recheck button that submits a form to reload the tab and run the requests again. No settings screen, no extra database tables, no JavaScript.
Steem