Key Takeaways
- Caching is the single biggest speed win available to most WooCommerce stores, and applied carelessly it is also one of the fastest ways to break a checkout. The difference between the two is entirely in what you exclude.
- Cache the pages that look identical for every visitor: the homepage, product pages, category and shop pages, blog posts, and static marketing pages.
- Never HTML-cache the Cart, Checkout, or My Account pages, and exclude WooCommerce’s session and cart cookies. WooCommerce’s own documentation is explicit that these pages must stay dynamic, and the cookie exclusions keep any shopper with an active basket on a freshly built page rather than a stored copy.
- Run two layers, not one: a page cache for static pages, and an object cache (Redis or Memcached) for the dynamic pages and database queries a page cache can never touch.
- The most common cache disasters (customers seeing each other’s carts, items reappearing after removal, stale prices, password reset loops, broken tracking) are all preventable with correct exclusions, and all invisible to the logged-in admin who set them up.
Caching is your biggest speed lever, and your easiest mistake
Every time someone loads a WooCommerce page that isn’t cached, your server rebuilds it from scratch: PHP runs, the database gets queried, the theme assembles the HTML, and only then does the page start loading.
Caching skips most of that. It saves a finished copy and hands it to the next visitor, which is far faster than rebuilding it every time.
For a content-heavy store, that’s the gap between a homepage that loads in half a second and one that crawls, which is why it’s usually the first lever we pull on a sluggish store.
For the wider set of causes, see our guide to why a WooCommerce store slows down.
Here’s the catch. A store is not a blog. A blog page looks the same for everyone, so caching it is risk-free.
A WooCommerce store is full of pages that differ for every shopper: their cart, checkout, account, and order confirmation. Serve a saved copy of one of those and you don’t get a faster store, you get a broken one.
And you almost never see the breakage yourself. Most setups bypass the cache for logged-in users, and you, the store owner, are logged in.
So your cart works perfectly while a logged-out customer in another city stares at someone else’s basket.
The store looks fine from where you’re sitting. That’s exactly why “it works for me” is not a test.
What to cache: the pages that belong to everyone
Start with the easy wins. These pages are identical for every visitor, so a cached copy serves everyone correctly and loads fast:
- The homepage. High traffic, fully static, the perfect candidate.
- Product pages. The product view itself doesn’t change per visitor (the Add to Cart action does, more on that shortly).
- Category and shop pages. Your product listings and archives.
- Blog posts and resource pages. Pure content.
- Static marketing pages. About, contact, landing, and policy pages.
These make up the bulk of your traffic and are where caching pays off hardest. Cache them aggressively.
What should I cache on a WooCommerce site? Cache every page that looks the same for all visitors: homepage, product, category and shop pages, blog posts, and static marketing pages. Avoid caching anything personalised to an individual shopper, such as the cart or account area.
What to never cache: the three pages that belong to one shopper
This is the rule that matters most, and it isn’t a matter of opinion. WooCommerce’s official developer documentation names three pages that must be excluded from caching:
- Cart
- Checkout
- My Account
The reason is simple: these pages display information specific to the current customer and their cart. A cached cart shows one person’s items to the next visitor.
A cached checkout shows stale totals or a payment form that won’t submit.
A cached My Account page can trap people in a password reset loop, which the documentation calls out by name.
In practice I’d add a fourth, the order-received (thank-you) page, since it’s unique to one completed order and usually carries your conversion tracking.
Most reputable plugins (WP Rocket, LiteSpeed Cache, FlyingPress) exclude the first three automatically, but don’t treat that as a guarantee.
A custom checkout built by a funnel plugin can slip past automatic detection, and server-level or CDN caching often doesn’t know about WooCommerce at all.
It’s also important to verify that dynamic WooCommerce requests are bypassing the cache correctly.
That includes URLs using the add-to-cart=* query parameter and AJAX requests that run through wc-ajax=*, both of which need to remain dynamic for cart and checkout functionality to work properly.
Most modern caching solutions handle these exclusions automatically, but it’s worth confirming the rules are in place rather than assuming every layer of your caching setup is WooCommerce-aware.
Which WooCommerce pages should never be cached?
Cart, Checkout, and My Account, plus the order-received page.
WooCommerce’s documentation states these must be excluded from HTML caching because they contain content unique to each shopper. Caching them breaks checkout and can expose one customer’s details to another.
In practice, the exclusion list is usually a little broader. Order Pay pages, Add Payment Method pages, Lost Password pages, and customer account dashboard endpoints should also remain dynamic, since they display customer-specific information or perform actions tied to an individual account.
If you’re using custom checkout flows, membership plugins, or account extensions, review those pages as well to ensure they aren’t being cached accidentally.
The cookies that protect your active shoppers
Excluding the pages is half the job. The other half is cookies, and it’s where a lot of careful setups fall down.
When a shopper adds something to their basket, WooCommerce sets cookies that signal “this person has an active session, give them a fresh page, not a cached one.”
If your cache ignores those cookies, it can serve a stored copy to someone who has items in their cart, and that’s how stale baskets and cross-customer leaks happen.
WooCommerce’s documentation lists the cookies to exclude from caching:
| Cookie | What it does |
| woocommerce_cart_hash | Tells WooCommerce when the cart contents or totals have changed. |
| woocommerce_items_in_cart | Tells WooCommerce when the cart contents have changed. |
| wp_woocommerce_session_ | Holds a unique code per customer so WooCommerce can find that customer’s cart in the database. |
| woocommerce_recently_viewed | Powers the Recently Viewed Products widget. |
| store_notice[notice id] | Lets a customer dismiss the store notice banner. |
Add these to your plugin’s “Never Cache Cookies” list. The label varies by plugin, but the setting exists in all the major ones. One extra note if your setup includes database or object caching: WooCommerce also recommends excluding _wc_session_ from the database cache where that option exists (some plugins, such as W3 Total Cache, handle this automatically).
Which WooCommerce cookies should I exclude from caching? The main ones are woocommerce_cart_hash, woocommerce_items_in_cart, wp_woocommerce_session_, and woocommerce_recently_viewed. Excluding them keeps any shopper with an active session on a freshly built page showing their own correct cart, not a stored generic one.
Cart fragments: how a cached page still shows a live cart count
Here’s what trips people up: if you cache the homepage and its header shows a live “2 items in cart” counter, how does the cached copy show the right number?
The answer is cart fragments. WooCommerce fires a small background request (you’ll see ?wc-ajax=get_refreshed_fragments in your network tab) that updates only the dynamic bits, like the mini-cart count, without reloading the page.
That’s the trick that lets you cache the full page while still showing each shopper their own basket: the page is static, the counter is patched in live.
This used to fire on every page load across the whole site, adding an extra uncached request even on pages with no cart widget.
WooCommerce changed that in version 7.8, so the script now runs only where it’s needed (pages with the cart widget active, where a third-party script depends on it, or where a developer explicitly enqueues it), and its developer blog documents the change.
For most modern stores it’s a non-issue now, but if your store predates that update or a plugin loads fragments everywhere, it’s worth checking.
On a high-traffic store, an unnecessary fragments call on every page is a real drag, and it’s the kind of thing we catch when we monitor a store’s health.
Page cache versus object cache: a busy store needs both
People think of “caching” as one thing. It’s two, and they solve different problems.
A page cache stores the finished HTML of your static pages. It’s what makes your homepage and product pages fast, and it’s the layer that must never touch Cart, Checkout, or My Account.
An object cache stores the results of repeated database queries in memory, so WooCommerce doesn’t ask the database the same expensive question over and over; it recommends Redis or Memcached for this.
Crucially, an object cache speeds up exactly the pages a page cache can’t: cart, checkout, account, and the admin dashboard, because those run live every time and lean heavily on the database.
It also lowers your server response time across the board.
So the layers cover each other: the page cache handles the static front-of-house, the object cache handles the dynamic, database-heavy work behind it.
A small store runs happily on a page cache alone, while a busy store, or one with a large catalogue, wants both.
The catch is that Redis or Memcached has to be available on your server, which usually means a VPS or a managed WooCommerce host rather than entry-level shared hosting. We go deeper on this for high-traffic and enterprise stores.
Do I need Redis, or is a caching plugin enough?
A plugin handles page caching for your static pages, which is essential.
Redis or Memcached object caching is a separate layer that speeds up the dynamic pages a page cache can’t serve, like cart, checkout, and account.
A busy store wants both, and object caching usually requires a VPS or a managed host that offers it.
What breaks, and why you won’t notice until a customer does
Every caching disaster we get called in to fix traces back to a missing exclusion. Here are the failure modes and what causes each.
Customers see each other’s carts, or items they never added. A cart page got cached and served to multiple visitors.
Almost always a missing page exclusion, a missing cookie exclusion, or a CDN caching dynamic pages. Beyond confusing, it’s a real privacy problem if customer details are exposed.
Items reappear after a shopper removes them. A stale cached cart is being served instead of the live one. Same root cause: cookies or page exclusions not set.
Prices or stock are wrong. A cached product or cart page shows yesterday’s price or an out-of-stock item as available. This one is dangerous, because it can mean honouring a price you never intended.
Password resets loop endlessly. The customer keeps getting bounced back to the login screen.
WooCommerce names this exact symptom: it’s caused by the My Account page being cached, often by a host’s server-level cache the plugin can’t control.
Conversion tracking stops firing. A cached page can serve a version where the tracking script never runs correctly for the actual visitor, and JavaScript minification can corrupt the tracking code outright.
If your analytics look wrong after a caching change, start here.
Why are customers seeing the wrong cart or each other’s carts? It’s a misconfiguration, nearly always missing cookie or page exclusions, or a CDN caching dynamic pages.
Exclude Cart, Checkout, and My Account, exclude the WooCommerce session and cart cookies, and apply the same rules at your CDN.
On minification specifically, because it surprises people: it’s usually fine for CSS but risky for JavaScript, and WooCommerce explicitly recommends avoiding JavaScript file minification.
The scripts running your cart, checkout, payment gateways, and tracking are exactly the ones it tends to break. If something fails right after you enable it, that’s your culprit, so turn it off or exclude the specific scripts and retest.
How to set caching up without breaking your store
Start safe, add risk deliberately, and test the purchase flow after every change. A fast store that can’t take an order isn’t fast. It’s broken.
- Turn on page caching for the static pages first.
- Confirm Cart, Checkout, My Account, and order-received are excluded. Most good plugins do this automatically; verify it, especially with a custom or funnel-built checkout.
- Add the cookie exclusions to the “Never Cache Cookies” list.
- Exclude logged-in users from page caching. Their experience is personalised and shouldn’t come from a shared cache.
- Add an object cache (Redis or Memcached) if your host supports it and your store is busy enough to need it.
- Introduce minification one feature at a time, testing after each, and treat JavaScript minification with particular caution or skip it.
- Mirror every page and cookie exclusion at your CDN or edge cache, marking cart, checkout, and account responses as private so no shared cache stores them.
Then test like a customer, not an admin. In a private window (logged out), load a product and a category page, add to cart then remove an item and confirm it actually goes, complete a full guest purchase and check the totals and payment, repeat logged in, apply a coupon, and reset a password.
Keeping this manageable over time is far easier with the right tools for the job in place.
Frequently Asked Questions
Does caching speed up the checkout page?
Not directly. The checkout can’t be page-cached because it’s unique to each shopper, so it runs live every time.
What helps is an object cache like Redis, which speeds up the database queries behind it, plus solid hosting and a low server response time. A slow checkout is a server-side fix, not a page cache.
Will my caching plugin exclude the right pages automatically?
The major plugins exclude Cart, Checkout, and My Account by default, but that’s only the page exclusions.
You still need to set the cookie exclusions, check that a custom checkout is recognised, handle minification carefully, and apply the same rules to any CDN. Treat automatic exclusion as a starting point, not the finish line.
Why does my store break when I enable minification?
JavaScript minification can corrupt the scripts your cart, checkout, payment gateways, and tracking depend on, which is why WooCommerce recommends avoiding it.
If a feature breaks right after, disable it and retest, or exclude the specific scripts. Always add performance features one at a time so you can tell which one caused the problem.
How do I test that caching hasn’t broken my store?
Test as a logged-out visitor in a private window, since logged-in admins usually bypass the cache and miss what guests see.
Load product and category pages, add and remove cart items, complete a guest purchase, repeat logged in, apply a coupon, and reset a password. If all of that works cleanly, your exclusions are right.
Can I cache pages for logged-in customers?
Generally no. Logged-in shoppers see personalised content, so a shared cached page risks showing them someone else’s information.
Most plugins disable page caching for logged-in users by default, and you should keep it that way. The object cache, not the page cache, is what speeds things up for them.
Does a CDN need the same cache exclusions?
Yes. A CDN caches whatever you let it, dynamic pages included. Apply the same exclusions you set in your plugin (Cart, Checkout, My Account, and the WooCommerce cookies) at the CDN level, and serve those pages as private.
Skip this and you re-introduce the cross-customer cart bug at the edge.
The Bottom Line
Caching is the most effective speed improvement available to a WooCommerce store, and the easiest to get dangerously wrong. The whole game is in the exclusions.
Cache the shared, static pages (home, product, category, blog, marketing) as hard as you like, keep Cart, Checkout, and My Account dynamic always, and add the cookie exclusions so active shoppers never get a stored page.
Layer in an object cache for the database-heavy work, mirror your exclusions at the CDN, and go easy on minification.
Then test the whole purchase flow as a logged-out customer, because that’s the only view that tells you the truth. Get it right and caching does its job: a noticeably faster store that still takes every order cleanly.
Get the exclusions wrong and you’ve built a fast store that quietly loses sales. If you’d rather have it set up and verified properly the first time, our WooCommerce developers do this for stores every week.




