WooCommerce

Speeding Up a Slow WooCommerce Store

Why WooCommerce stores get slow and what fixes them: object caching, the uncacheable pages, product queries, images and heavy extensions.

By 7 min read
Ascending bar chart with a rising trend line over the bars

WooCommerce stores get slow in a specific way. The homepage might score well while the shop archive crawls, or the front end is fine and the admin takes eight seconds to load an order list. That's not random — it follows from how a store differs from a content site.

This is the order I work through a slow store, and why each step is where it is.

First, find out what kind of slow it is

There are two completely different problems that both feel like "the site is slow", and treating one with the other's fix wastes a lot of time.

Server-side slow means a long time to first byte: the browser asks for the page and waits before anything arrives. That's PHP and MySQL — queries, plugins, hosting. Browser-side slow means the HTML arrives quickly but the page takes ages to become usable: that's images, CSS, JavaScript and third-party scripts.

Check the time to first byte in your browser's network panel. Over about 600ms on a cached page points at the server; well under that with a slow-feeling page points at the front end. Test the homepage, a product page, the shop archive and the cart separately — they behave very differently.

Object caching first

This is the highest-value change on most stores and the most frequently missing. WordPress caches query results in memory during a single request, but without a persistent backend that cache is thrown away the moment the page finishes.

Add Redis or Memcached and those results survive between requests. On a store this matters more than page caching, because the pages that hurt most — cart, checkout, account, and the whole admin — can never be page-cached. They have to be fast at doing the work, and object caching is how.

If your order list or product admin is slow while the front end is fine, this is almost certainly what's missing.

Page caching, with the right exclusions

Page caching still matters for everything anonymous: the homepage, category archives, product pages for logged-out visitors, blog posts. Just make sure cart, checkout, my-account and any page showing personalised content are excluded.

Getting this wrong is worse than not caching at all. A page cache that serves a cached cart will eventually show one customer another customer's basket, and on the checkout it can expose an address. Test it: add something to the cart in a private window, then check the cart page in a different private window and confirm it's empty.

Most WooCommerce-aware caching setups handle these exclusions by default, but verify rather than assume — especially after switching caching plugin or host.

Product queries and the postmeta problem

WooCommerce stores a great deal in wp_postmeta, and that table grows with your catalogue, your variations and your orders. Queries that filter or sort by meta values get slower as it grows, because they join a large table on values that aren't efficiently indexed.

  • Prefer taxonomy queries over meta queries where you have the choice — filtering by a product category is much cheaper than filtering by a custom field.
  • Reduce products per page on archives. Forty-eight products per page is forty-eight sets of meta lookups and forty-eight images.
  • Be careful with "sort by price" and price-range filters on large catalogues; these are meta queries by nature and often the slowest thing on the site.
  • Make sure WooCommerce's lookup tables are populated — they exist precisely to make these queries cheaper, and they can fall out of date after a bulk import.
  • Check for plugins running their own queries on every product in the loop. A related-products or stock-badge plugin doing one query per product is an N+1 problem.

Images, because a store is mostly images

  • Serve WebP or AVIF. On an image-heavy catalogue this alone can halve the page weight.
  • Register and use image sizes that match the display size. A 2000px product photo rendered in a 300px grid cell is wasted bandwidth on every card.
  • Keep srcset working so phones get phone-sized images.
  • Lazy-load below-the-fold product images, but never the main product image on a product page — that's usually the LCP element, and lazy-loading it directly delays the metric Google measures.
  • Watch product galleries and zoom plugins, which sometimes preload every high-resolution variant on page load.

The extension audit

Every extension adds PHP on the server and usually assets in the browser, and many load site-wide when they're only needed on one template. A store with thirty extensions is rarely fast, and the fix is rarely subtle.

Go through the list and ask, for each one: is this still used, does it load only where it's needed, and is it maintained? Deactivate anything unused and delete it — deactivated plugins are still a security and maintenance cost.

For the ones you keep, check what they enqueue. Dequeuing a review plugin's CSS on every page except product pages is a small change with a real effect on every other page of the store.

Cart fragments and other Woo-specific weight

WooCommerce refreshes the cart contents in the header with an AJAX call on page load, so a cached page can still show the right cart count. On a store where the header doesn't display a live cart total, that's a request on every page view for nothing.

Similarly, WooCommerce loads its cart and checkout scripts and styles across the whole site by default. On a store where most traffic lands on content pages, restricting those to the pages that need them is a straightforward win.

Both changes need testing against your actual theme — some themes depend on those scripts in places you wouldn't expect.

Hosting that suits a store

Shared hosting struggles with WooCommerce specifically because so much of a store can't be cached. You're paying for PHP and MySQL work on a meaningful share of requests, and on cheap shared hosting that work is competing with other sites on the same machine.

What to look for: PHP 8.x with OPcache, a persistent object cache available, MySQL with enough memory to keep the working set in RAM, and server-level page caching that understands WooCommerce. A host that markets itself on disk space rather than any of those is not a store host.

Housekeeping that adds up

  • Clear expired transients and orphaned metadata; WooCommerce generates a lot of both.
  • Move wp-cron to a real server cron so scheduled tasks don't run inside a customer's page load.
  • Trim old order sessions and abandoned cart data, which accumulate quietly.
  • Keep post revisions bounded — a product edited fifty times carries fifty rows.
  • Review the scheduled actions queue; a stuck or ballooning queue is a common hidden load source on busy stores.

Measure properly

Test logged out, in a private window, on the templates that matter: homepage, a product, the shop archive, the cart, the checkout. Test on a real mid-range phone on mobile data, not only on a desktop connection.

Change one thing at a time and re-measure. Stores have enough moving parts that batching five changes leaves you unable to say which one helped and which one broke the checkout.

Frequently asked questions

Why is my WooCommerce store slower than my blog?

Because a store's most important pages can't be page-cached. Cart, checkout and account pages differ per visitor, so the server has to build them every time. That makes hosting quality, object caching and query efficiency matter far more on a store than on a content site.

Does a caching plugin work with WooCommerce?

Yes, provided it excludes cart, checkout and account pages. Most WooCommerce-aware plugins do this by default, but verify it after any change of plugin or host: add an item to the cart in one private window and check the cart in another. If it isn't empty, the cache is serving personalised pages.

How many products can a WooCommerce store handle before it slows down?

The count itself is rarely the limit — stores with tens of thousands of products run fine on suitable infrastructure. What causes trouble is meta-heavy filtering and sorting, huge variation counts, and archives showing dozens of products per page. Fix the queries and the hosting rather than trimming the catalogue.

Should I disable cart fragments?

If your header doesn't show a live cart count, yes — it's an AJAX request on every page load for information nobody sees. If it does show one, disabling it will freeze that number on cached pages. Test your theme after changing it, because some themes depend on those scripts in unexpected places.

Is shared hosting good enough for WooCommerce?

For a small catalogue with light traffic it can be. It struggles as soon as uncacheable traffic grows, because you're competing for PHP and MySQL resources on every cart and checkout request. Look for PHP 8.x with OPcache, an available object cache, and server-level caching that understands WooCommerce.

Topics

  • WooCommerce speed
  • WooCommerce performance
  • slow WooCommerce
  • WooCommerce optimisation