How to Speed Up WooCommerce Without Breaking Checkout

WooCommerce is slower than a brochure site because it cannot cache the pages that matter most. Cart, checkout and account are different for every visitor, so they have to be built fresh each time. The work is making everything else cacheable, and making the uncacheable part cheap.
What can and cannot be cached
Your homepage, category listings and individual product pages are the same for everyone until someone adds to their basket. They should be served from cache. Cart, checkout, my-account and anything behind a login must bypass it, because serving one shopper another shopper’s basket is the worst bug a store can have.
WooCommerce signals this with cookies. Once a visitor has items in their basket, a woocommerce_items_in_cart cookie is set and the cache should step aside for that visitor. A correctly configured platform does this automatically. A generic caching plugin often does not, which is where the horror stories come from.
Object caching matters more than page caching
Because checkout cannot be page-cached, the only way to make it fast is to make the queries behind it fast. That is what a persistent object cache does: it keeps the results of expensive database lookups in memory so they are not recomputed on every request.
On a store with a few thousand products and a handful of extensions, a single checkout page load can fire hundreds of queries. Redis holding those results is usually the single biggest improvement available, and it is invisible to customers except that the page appears sooner.
Where store slowness actually comes from
Extensions running on every request. Shipping calculators, currency switchers and analytics hooks often run whether or not the page needs them.
Product image sizes. A 3000px photograph scaled down in the browser still downloads at full weight. Serve the size you display.
Unbounded queries. “Related products” and faceted filters can scan large tables. Limit them, and cache the result.
Autoloaded options. Abandoned extensions leave rows in the options table that load on every single request. Auditing this is unglamorous and frequently the fastest win available.
Test under the load you actually get
A store that is quick when you test it alone at nine in the morning may fall over during a campaign. The queries that matter are the ones that pile up concurrently. If you run sales, test with concurrency before the sale, not during it.
Watch the numbers that reflect customer experience: time to first byte on a product page, and completion time on checkout. A homepage score of 100 tells you very little about whether people can buy things.
Do not install a caching plugin on top of a caching platform
If your host already caches at the edge and provides an object cache, adding a caching plugin creates two systems with different ideas about what is stale. The symptoms are maddening: prices that update for some visitors, baskets that empty, a checkout that works until it does not. Pick one layer and let it do its job.
The short version
Cache the catalogue at the edge, never cache the basket, put the database results in memory, and audit what your extensions do on every request. Those four things account for most of the difference between a store that holds up on launch day and one that does not.
More from the blog
Other notes on keeping WordPress sites fast, secure and upright.
September 7, 2026
Fix Mixed Content Warnings on WordPress
Padlock warning after moving to HTTPS? Find the http URLs, rewrite them safely with WP-CLI, and avoid the serialized-dat...
September 7, 2026
WordPress Contact Form Not Sending Email
Forms reporting success but nothing arrives? Why wp_mail() cannot tell you, how to check if mail left at all, and the SM...
September 7, 2026