A store can feel fast when you browse its homepage and still behave badly when a customer adds a product to the cart. The quantity changes, then changes back. A discount appears only after a refresh. Checkout keeps loading while the customer wonders whether to try again.
Caching is one possible cause, especially after a hosting move or a performance plugin change. The useful question is not simply whether caching is switched on. It is which responses are being reused, where they are stored, and whether they belong to one shopper.
Start with the pages that belong to a customer
WooCommerce’s caching configuration guide says Cart, Checkout, and My Account should remain dynamic because their content depends on the customer. It also documents cart and session cookies, including woocommerce_cart_hash, woocommerce_items_in_cart, and the wp_woocommerce_session_ prefix.
Use those documented signals through your cache provider’s WooCommerce integration. Avoid copying a generic “cache everything” recipe into a live store. Check the actual page assignments and URLs, including translated or renamed pages. An exclusion for /checkout/ is no help if the store uses a different path.
For a custom store, I would also review any page showing a points balance, saved addresses, private pricing, or a personal quotation. Decide how that content stays specific to its owner before enabling shared page caching around it.
Separate page caching from the other performance settings
Several settings can sit inside one plugin, but they do different jobs. Page caching reuses a generated response. Object caching reuses application data. Browser caching stores resources locally, and a CDN can keep responses closer to visitors. JavaScript delay or combination changes how scripts load; it is a separate troubleshooting variable.
Make a short inventory of the store’s actual layers: WordPress plugin, host cache, reverse proxy, CDN, and any custom application cache. Record who controls each one. Otherwise, you can disable a plugin and still receive an older response from a cache in front of WordPress.
My approach is to establish a working baseline on staging, then reintroduce one performance feature at a time. Record the setting and test result together. Changing five switches at once may make the symptom disappear, but it leaves you without a dependable explanation.
Check the API requests as well as the visible page
WooCommerce’s checkout troubleshooting documentation distinguishes Checkout blocks, which use the Store API, from classic checkout, which uses WooCommerce AJAX requests. It advises keeping the relevant dynamic requests out of page and edge caches, not just excluding the checkout page itself.
Open the browser’s Network panel and reproduce one failed action. Inspect the request URL, method, status, and response body. A successful HTTP status does not help if the body contains an unexpected login page, stale content, or an error instead of the response the checkout code expects.
Do not assume every spinner is a caching problem. A blocked payment script, a PHP failure, or an incompatible extension can look similar. Save the first relevant console error and failed request, then use that evidence to choose the next check. Use a staging copy and sandbox payment settings for order tests.
Run a two-shopper test
Testing while signed in as an administrator can miss guest behavior. For a more useful test, create two independent browser profiles or use different browsers. Two tabs in one profile normally share cookies. Two private windows in the same browser may also share a private session.
- In session A, add one blue product. In session B, add two cream products. Write down the expected contents and totals.
- Visit the same public product page in both sessions, then return to each cart. Confirm the cart and header mini-cart still match that shopper.
- Change a quantity in A, remove an item in B, and refresh both. Neither action should affect the other session.
- Apply a test coupon in A. Confirm B’s totals do not inherit it.
- Sign in with two separate test customer accounts. Check account details and any customer-specific rewards display.
- Complete a sandbox order and confirm the resulting order’s items and totals agree with that shopper’s final checkout.

AI-generated photorealistic editorial scene of two laptops displaying different generic shopping pages, beside a paper checklist. Conceptual image illustrating separate customer sessions; not evidence of an actual test.
Conceptual AI-generated editorial image illustrating separate shopping sessions. It is not a screenshot or evidence of an actual store test.
Run the sequence after the public pages have been visited enough to populate the caches. A fresh cache can hide the problem because nothing has been reused yet. Repeat after a purge and again with the cache populated. Keep a small test log with the browser profile, action, expected result, and actual result.
Read cache evidence without overinterpreting it
In Network, inspect response headers such as Age, Cache-Control, and any provider-specific cache status. Their meaning depends on the layer that issued them. A MISS on one request is not proof that an entire checkout flow is excluded: the next request could be a HIT, and another cache may exist upstream.
The HTTP caching standard, RFC 9111, makes an important distinction: no-cache requires validation before reuse; it does not mean “never store.” The no-store directive prohibits storage, while private prevents storage by a shared cache but can allow a browser’s private cache. These are different policies.
For custom personalized responses, choose an appropriate policy and check that your proxy and CDN honor it. Adding a header in PHP cannot fix a rule that serves an already stored response before PHP runs. Correct the rule, purge the affected cached responses, then repeat the test.
Defaults help, but verify the store’s configuration
LiteSpeed’s cache settings documentation says Cart, Checkout, and My Account are excluded by default. It also warns that incorrect WooCommerce page associations can cause misclassification. That is a good reason to inspect configuration and observed responses together.
Do not stack page-cache plugins in the hope that their benefits add together. Choose a supported setup for the hosting environment, document its exclusions, and check the host or CDN settings separately. If a provider offers advanced caching for dynamic fragments, use its documented WooCommerce behavior and verify isolation rather than improvising a shared cache key.
For loyalty or pricing extensions, include a deliberate account-change test. Give two test customers different balances or pricing eligibility, then switch between them using isolated profiles. Check both the displayed value and the value used when the order is calculated. A correct-looking label alone does not prove the business rule is working.
What to keep in the handover notes
- The cache layers in use and where their settings live.
- The actual cart, checkout, account, and custom personalized routes.
- The session and request exclusions required by the installed integrations.
- A short repeatable guest and customer test, including coupons and custom checkout features.
- The steps to purge each layer and undo the most recent configuration change.
Once the shopping flow is dependable, measure public-page performance and optimize from that baseline. There is still room to reduce image weight, remove unnecessary scripts, and investigate slow application work without treating every response as interchangeable.
For related custom WooCommerce work, see my Swarm Rewards loyalty plugin integration. The test examples here are illustrative, not claims about that project’s cache configuration. If you need help making a custom store feature work reliably with your hosting and cache setup, I’m happy to discuss it.
Documentation checked on 1 November 2026. Match any configuration change to the versions and hosting stack used by your store.



