WooCommerce CRO Technique

How to cache a WooCommerce store safely without breaking cart and checkout

This technique uses full-page caching for anonymous WooCommerce catalogue traffic such as shop, category and product pages, while explicitly bypassing Cart, Checkout, My Account and the cookies or sessions that make those pages user-specific.

Summary

Bottom Line: Cache WooCommerce’s public catalogue pages, but never cache Cart, Checkout or My Account, because they are session-specific and can show the wrong cart or account state if cached.

  • Do not assume the plugin “has WooCommerce covered” just because it says it does; verify the actual pages assigned under WooCommerce → Settings → Advanced and confirm those exact URLs are being bypassed in every cache layer. LiteSpeed explicitly warns that wrong page associations can make the wrong pages cacheable or non-cacheable.
  • Checkout is especially sensitive to JavaScript optimisation. WooCommerce’s own caching guidance says to avoid JavaScript minification, classic checkout refreshes totals and payment methods via AJAX, and Checkout Blocks depend on Store API data plus client-side payment registration.
  • Host-level caching can override or sit above plugin rules. WP Rocket notes that on some hosts you must ask the host to apply exclusions, while Kinsta and WP Engine both document server-side WooCommerce cache rules.
  • Persistent object cache is a different layer. WordPress says the object cache reduces trips to the database, but it is non-persistent by default; persistent backends such as Redis or Memcached help database-heavy work across requests, while full-page cache is what speeds cacheable public pages.

How To Implement

  • Start in WooCommerce → Settings → Advanced → Page setup and confirm the live Cart, Checkout and My Account assignments

    Start in WooCommerce → Settings → Advanced → Page setup and confirm the live Cart, Checkout and My Account assignments. WooCommerce requires separate pages for these functions, and wrong page assignments can cause redirects and gateway problems before caching even enters the picture. If you are on the modern block flow, the Cart and Checkout pages should contain the WooCommerce blocks; if you are still on legacy templates, the classic shortcodes are [woocommerce_cart], [woocommerce_checkout] and [woocommerce_my_account].

  • Decide which layer actually owns full-page cache on the live site

    Decide which layer actually owns full-page cache on the live site. WooCommerce recommends server-side caching or WordPress caching plugins for performance, but dynamic content like cart and checkout must remain uncached. If the host already applies server-level cache, treat that as the source of truth; WP Rocket explicitly notes that on some hosts its exclusions do not manage the host cache layer for you.

  • Enable or keep full-page cache for anonymous catalogue traffic only

    Enable or keep full-page cache for anonymous catalogue traffic only. The target here is public shop, category and product traffic, not any page that reflects the current customer’s cart, address, payment options or account. Measurement note: record a baseline on two or three representative product/category URLs before changing anything, because web.dev recommends using field data as the primary source for TTFB rather than relying only on lab runs.

  • Verify the exclusion list in the actual cache plugin

    Verify the exclusion list in the actual cache plugin:

    • WP Rocket: WooCommerce pages assigned in settings are excluded automatically behind the scenes. If you use custom paths, unusual slugs, or just want to make the rule explicit, go to Settings → WP Rocket → Advanced Rules → Never Cache URL(s) and add the URLs. WP Rocket also notes that excluding a page from cache excludes it from its other optimisations too.
    • LiteSpeed Cache: Cart, Checkout and My Account are excluded by default, but LiteSpeed warns that wrong WooCommerce page associations can cause pages to be misclassified. Check LiteSpeed Cache → Cache → WooCommerce and, where needed, add rules under LiteSpeed Cache → Cache → Excludes → Do Not Cache URIs.
  • Verify exclusions in the host/server cache as well, not just in WordPress

    Verify exclusions in the host/server cache as well, not just in WordPress. Kinsta documents that cart, my-account and checkout are excluded server-side and that visitors bypass cache when woocommerce_items_in_cart is present; WP Engine documents default exclusions for cart and checkout paths and adds extra WooCommerce exclusions when WooCommerce is detected. If your host owns the page cache, plugin-side exclusions alone are not enough evidence.

  • Exclude WooCommerce session and cart cookies from any cache layer that supports cookie or session bypass

    Exclude WooCommerce session and cart cookies from any cache layer that supports cookie or session bypass. WooCommerce’s own caching guide lists woocommerce_cart_hash, woocommerce_items_in_cart and wp_woocommerce_session_ as the key cookies involved in cart/session behaviour, and recommends excluding _wc_session_ from database caching if your stack offers that kind of cache. This is the part that prevents one visitor being served another visitor’s cart state.

  • Keep checkout out of aggressive JavaScript optimisation

    Keep checkout out of aggressive JavaScript optimisation:

    • WooCommerce’s caching documentation explicitly says it recommends avoiding JavaScript minification.
    • On classic shortcode checkout, the “review order” area loads payment methods and totals using AJAX, so broken or deferred scripts can leave an endless spinner or missing fields.
    • On Cart & Checkout Blocks, server-side cart and checkout data is hydrated into wc/store/cart and wc/store/checkout, and payment methods are registered client-side. That means block checkout is not “safe by default” from script optimisation issues just because it is newer.
    • WP Rocket: use Settings → WP Rocket → File Optimization to relax or exclude problem scripts. The official docs describe Excluded JavaScript Files and Load JavaScript Deferred exclusions, matched by full URL, keyword or wildcard.
    • LiteSpeed Cache: use LiteSpeed Cache → Page Optimization → Tuning. LiteSpeed documents JS Excludes, JS Deferred/Delayed Excludes, Guest Mode JS Excludes, and URI Excludes for excluding either the scripts themselves or the checkout URI from optimisation.
  • Include the dynamic endpoint families in your checks, not just the three top-level pages

    Include the dynamic endpoint families in your checks, not just the three top-level pages. WooCommerce appends checkout endpoints such as Pay, Order received and Add payment method to the checkout page URL, and My Account endpoints such as Orders, Payment methods, Lost password and Logout to the account URL. WooCommerce also warns that a cached My Account page can cause password-reset loops.

  • If the store is database-heavy, add a persistent object cache separately from page cache

    If the store is database-heavy, add a persistent object cache separately from page cache. WordPress says the object cache reduces database trips, but it is non-persistent by default; persistent backends keep cache across page loads. Redis and Memcached are the common in-memory options. HPOS is worth enabling where compatible because it moves order storage to dedicated tables from WooCommerce 8.2 onwards, but HPOS does not remove the need to keep cart, checkout and account dynamic.

  • Purge every relevant layer, then verify with headers and real journeys

    Purge every relevant layer, then verify with headers and real journeys:

    • On LiteSpeed, excluded pages should return the X-LiteSpeed-Cache-Control: no-cache header.
    • On Kinsta, a repeat request to a cacheable public page should show X-Kinsta-Cache: HIT; checkout/cart/account should still bypass.
    • On WP Rocket, use the ?nowprocket version of a URL when you need to inspect an uncached, unminified version during JS troubleshooting.
  • Finish with a manual smoke test before calling it done

    Finish with a manual smoke test before calling it done. Test guest and logged-in users, add-to-cart, mini-cart/cart, coupon application, shipping recalculation, checkout field edits, gateway field rendering, order-pay, add-payment-method, password reset, and My Account pages on at least Chrome, Safari and Firefox. The goal of this technique is faster public pages with zero checkout or session regressions.

How To Measure

The primary technical KPI is TTFB on cacheable catalogue URLs, with LCP as the supporting UX KPI on the same public pages. web.dev recommends field data as the primary way to judge TTFB, and Google’s current Core Web Vitals thresholds remain LCP ≤2.5s, INP ≤200ms and CLS ≤0.1 at the 75th percentile. Read this in PageSpeed Insights and Search Console’s Core Web Vitals report for a stable set of public product/category URLs.

For business impact, use GA4 Funnel exploration with the ecommerce events begin_checkoutadd_payment_infopurchase. Segment the funnel by Device category and Browser, because cache or JS regressions often show up first on one browser/device mix rather than sitewide. For affected landing pages, use Landing page + query string or Page path to isolate the product/category URLs touched by the caching change.

A practical commercial read is:

  • Checkout completion = purchases ÷ begin_checkout for the same period and segment.
  • RPV = purchase revenue ÷ sessions for the affected landing-page segment.
  • Success = lower TTFB and ideally better LCP on public catalogue pages, with flat or improved checkout completion and no browser-specific drop-off. GA4 documents the sessions and purchase revenue metrics you need for that read.

Guardrail metrics that must not get worse: overall conversion rate, RPV, AOV, begin_checkoutadd_payment_info progression, add_payment_infopurchase progression, and browser/device-specific funnel completion. If you have a custom checkout-error event, include that as a hard guardrail too; if not, use the manual QA matrix above as the release gate.

Pitfalls

  • “If I exclude /checkout/, the rest of the customer flow is covered.” Not always. WooCommerce checkout and My Account use appended endpoints such as pay, order received, add payment method, payment methods and lost password, and WooCommerce explicitly warns that a cached My Account page can cause password-reset loops.
  • “JavaScript minify/combine is a free win on checkout.” It is not. WooCommerce recommends avoiding JavaScript minification in its caching guide, classic checkout uses AJAX for totals and payment methods, and Checkout Blocks still depend on client/server script orchestration for cart, checkout and payment flows.
  • “Persistent object cache replaces page cache.” It does not. WordPress object cache reduces database work, while full-page cache serves cacheable HTML to anonymous visitors; they solve different bottlenecks.
  • “HPOS means frontend caching is basically solved.” No. HPOS changes where order data is stored and improves database efficiency, but WooCommerce’s page-cache rule still stands: cart, checkout and account must remain dynamic.

Examples

FAQs

Sources & Further Reading

Want us to implement this for you?

We run measured CRO consultancy for WooCommerce. If you want help prioritising, testing & implementing these improvements, tell us about your store.

Book Pilot

About This Page

  • Written By: Eliot Webb – Founder & WooCommerce CRO Consultant
  • Last Reviewed: 18 Jun 2026
  • Last Updated: