How to speed up a WooCommerce store
A store is harder to make fast than a blog because the cart, checkout and account pages are built fresh for every customer. Cache every page that can be cached, keep those three out, and make the rest cheap to build with suitable hosting, an object cache and a tidy database.
- By
- WP Ministry
- Updated
In short
- Cart, Checkout and My account can never be served from a page cache. Every other page can.
- Measure a product page, the cart and the checkout, not only the home page.
- A page cache hides a slow server on cached pages. The checkout shows the server's real speed.
- A persistent object cache helps most on the pages a page cache cannot touch.
- Check that the store uses High-Performance Order Storage, and switch an older store over with care.
- After every speed change, place a test order in a private window.
On a blog, every visitor to a post gets the same page. A page cache builds that page once, stores it, and hands out the copy. That one step does most of the work of making a WordPress site fast.
A store cannot do that everywhere. The cart, the checkout and the account pages show something different to each customer, so PHP and the database have to build them every time someone asks. A store with a quick home page can still have a slow checkout, and the checkout is where orders are placed.
So the work has two halves. Cache every page that can be cached. Then make the pages that cannot be cached cheap to build. This page covers what a store needs on top of the steps in how to speed up WordPress.
Measure the pages that matter
Testing the home page alone tells you little about a store. Test the pages a customer passes through on the way to paying.
- A product page and a category page. Run each through PageSpeed Insights. It gives a lab test of the page as it loads now, and figures from real visitors over the previous 28 days where it has enough of them.
- The cart and the checkout. A testing tool arrives as a new visitor with an empty cart, so test these yourself. Open a private browser window, add a product to the cart, open the browser's developer tools on the Network panel and load the cart page, then the checkout. The time shown for the first request in the list is how long the page itself took to arrive.
Test without logging in, because many caches skip logged-in users. Write the figures down, change one thing at a time, and measure again.
Hosting sized for the store
A page cache hides a slow server from most visitors, because a stored page takes almost no work to send. The cart and the checkout get no such help. If those pages are slow on a store with few extensions, the hosting is the limit and no plugin will change that.
WooCommerce publishes what it expects of a server: PHP 8.3 or greater, MySQL 8.0 or MariaDB 10.6 or greater, a WordPress memory limit of at least 256 MB, and HTTPS. It warns that a server below its requirements may perform poorly. To see what your store runs on, go to WooCommerce, then Status. The report lists the PHP version, the database version, the memory limit and whether an external object cache is in use.
Three questions to put to your host: which PHP version the store is on, whether a persistent object cache is available on your plan, and whether the host's own cache leaves out the WooCommerce pages named below.
A page cache that leaves out the right pages
Product pages, category pages and the shop page look the same to every visitor who has nothing in the cart, so they can be cached. WooCommerce's guide to configuring caching names three pages that must stay out: Cart, My account and Checkout.
Step 1: List every cache in front of the store
There may be more than one: a caching plugin, a cache your host runs, and a content delivery network. Each needs the same exclusions.
Step 2: Exclude Cart, My account and Checkout
WooCommerce's guide says caching plugins often exclude these already. Check anyway. A changed page address or a reset setting can undo it.
Step 3: Exclude WooCommerce's cookies
If the cache has a setting for cookies, list these, so a visitor with something in the cart is given a fresh page and not a stored one. WooCommerce's guide also lists
woocommerce_recently_viewedand the cookie for a dismissed store notice.textwoocommerce_cart_hash woocommerce_items_in_cart wp_woocommerce_session_Step 4: Test with two browsers
Empty every cache. In a private window, add a product to the cart. In a different browser, open the cart page: it should be empty. Then place a test order.
If a cache does store one of these pages, customers see another person's cart, the checkout rejects orders, or a password reset sends them round in a loop. WooCommerce's guide traces that last one to a host's cache storing the My account page. How to fix a WooCommerce checkout that is not working covers the repair.
Then check the other half: that product and category pages are in fact being cached. Under Tools, then Site Health, WordPress checks whether a page cache is in place and whether the server answers quickly enough. For how the common caching plugins handle a store, see WordPress caching plugins compared.
Be careful with settings that minify or combine JavaScript. WooCommerce's guide recommends against JavaScript minification in its notes on one caching plugin. If the cart or checkout misbehaves after you switch such a setting on, switch it off first.
An object cache for the pages that cannot be cached
WordPress keeps the results of database queries in an object cache so that it does not ask the database the same thing twice. By default that cache lasts only for the one request and is then thrown away. A persistent object cache keeps it between requests, using a service such as Redis or Memcached on the server.
This is the cache that helps the cart, the checkout, the account pages and the dashboard, because it works below the level of the page. It needs the service to be running on the server, so ask your host whether your plan includes it and which plugin they recommend to connect it. Site Health suggests a persistent object cache when it judges the site would benefit.
If your caching setup offers database caching, WooCommerce's guide suggests keeping _wc_session_ out of it.
High-Performance Order Storage
Before version 8.2, WooCommerce kept orders in the same database tables WordPress uses for posts and pages. High-Performance Order Storage, or HPOS, keeps them in tables of their own, with their own indexes. WooCommerce's documentation gives the reason as scale: fewer reads and writes, and fewer busy tables, as the number of orders grows.
HPOS is on by default for stores first installed with WooCommerce 8.2 or later. An older store may still be on the old tables. To see which, go to WooCommerce, then Settings, then Advanced, then Features, and look at "Order data storage".
Step 1: Take a backup, and try it on a copy first
The switch changes where every order is stored. Rehearse it on a staging site if you can.
Step 2: Check your extensions
If an extension is not compatible with HPOS, the option to switch is disabled. A "View and manage" link beside it lists the extensions concerned. Update them, or ask their developers.
Step 3: Bring the two sets of tables into step
Tick "Enable compatibility mode (Synchronize orders between High-performance order storage and WordPress posts storage)" and save. WooCommerce copies the orders across in the background. You can follow the progress under WooCommerce, then Status, then Scheduled Actions.
Step 4: Switch
When the tables match, select "High-performance order storage (recommended)" and save. WooCommerce's documentation advises leaving compatibility mode on for some time afterwards, and says you can go back to the old storage at once if something is wrong.
Step 5: Place a test order
Then check that it appears under WooCommerce, then Orders, and that your payment, shipping and email extensions handled it.
Keep the database tidy
A store writes to the database all day: sessions for each visitor with a cart, temporary data that WooCommerce keeps to save work, and background jobs. Most of it clears itself. Look when the dashboard or the checkout has become slow over time.
The tools are under WooCommerce, then Status, then Tools. Take a backup before using one that deletes.
| Tool | What it does | When to use it |
|---|---|---|
| "Expired transients" | Removes temporary data that has passed its expiry | Routinely. Nothing in use is touched. |
| "WooCommerce transients" | Clears temporary data about the shop and its products | When product data looks out of date. WooCommerce builds it again as needed. |
| "Product lookup tables" | Rebuilds the tables that hold product data for quick access | When they are out of step with the products. |
| "Clear customer sessions" | Deletes every ongoing session, cart contents included | Rarely, and at a quiet hour. Every customer's cart is emptied. |
With WP-CLI, one command removes expired transients:
wp transient delete --expiredNext, open WooCommerce, then Status, then Scheduled Actions. This is the queue of background jobs for WooCommerce and its extensions. Filter it to the failed ones and open an entry's log to see why it failed. A few past-due actions are normal. Several that are more than a day old suggest that background jobs are not running as they should, which is worth raising with your host.
Product images
Product pages are mostly pictures, so images are where a cached page still loses time.
WooCommerce recommends uploading product images at least 800 by 800 pixels, and it uses each in three sizes: the single product image, the catalog image and the thumbnail. In a classic theme, their widths are set under Appearance, then Customize, then WooCommerce, then Product Images. The section is missing when the theme sets its own sizes, and block themes hide the Customize menu.
After changing a size, run "Regenerate shop thumbnails" under WooCommerce, then Status, then Tools. It remakes the shop images in the background.
Compression, WebP and AVIF, and lazy-loading work on a store as on any WordPress site. How to optimize WordPress images covers them.
Fewer extensions
Every active extension runs its code on every request, the uncached ones included. Many also add scripts and styles to the cart and checkout whether or not they are needed there.
- Remove what you do not use. Deactivate it, check the store, then delete it.
- Find the expensive ones. Query Monitor, a plugin in the WordPress.org directory, shows the database queries behind a page and groups them by the plugin or theme responsible, with slow and duplicate queries marked. Use it on the cart and the checkout.
- Compare with and without. On a staging copy, deactivate one extension, measure the checkout, and reactivate it. A large difference tells you where to look.
- Look at what the checkout loads from other companies. Chat widgets and tracking scripts add to the page a customer is trying to pay on. Keep only the ones that are needed there.
Each change here can break the thing you are speeding up. After any change to caching, extensions or order storage, go through the checkout in a private window before you call it done: on a staging copy with the gateway in test mode, a full test order; on the live store, as far as the payment step without paying, then watch the next real orders reach "Processing".
Our speed optimization service is a one-time job that measures the pages you name, such as a product page, the cart and the checkout, before the work and again after it. The Store plan described under WooCommerce maintenance includes a quarterly speed tune-up and a checkout and payment test after every update.
Common questions
Should I switch off cart fragments?
On a current store there is usually no need. Cart fragments is the script that refreshes the cart widget after a product is added. Since WooCommerce 7.8 it is no longer loaded on every page by default, only where that widget is shown or another script asks for it. WooCommerce's developers recommend the Mini-Cart block in place of the older widget, because the block does not use cart fragments.
Will a CDN make the checkout faster?
Only its static parts. A CDN serves images, styles and scripts from a server near the customer. The checkout page itself is still built on your own server for each customer. If your CDN also caches pages, give it the same three exclusions. See how to set up a CDN for WordPress.
How fast is fast enough?
Google counts a page as good when its largest element appears within 2.5 seconds, it responds to a tap or click within 200 milliseconds, and its layout shift score is 0.1 or less. Those are the Core Web Vitals, and how to improve Core Web Vitals explains each one. For the cart and checkout, compare your own figures before and after each change.

