NEWS
Checkout Files Upload for WooCommerce lets anyone upload PHP. See whether yours is affected
WooCommerce

7 causes of a slow WooCommerce store and how to fix them

# TagsWooCommerceSpeed
The WPhost team18 min read

Product pages open slowly, adding to the cart takes several seconds, and during a campaign the store starts throwing errors. A slow WooCommerce store rarely has just one cause, so the first job is to work out which of the usual ones apply to yours.

Below are seven of the most common causes. For each one we explain how to find it and how to fix it. The general steps for caching, images and PHP are in the guide Speed up WordPress with a cache, lighter images and new PHP, so here we focus on what is specific to an online store. At the end we explain when tuning stops paying off.

How to find out why your WooCommerce store is slow

Start by measuring. Run the home page, one category, one product and the cart through PageSpeed Insights, on mobile, five times each. How to measure properly, and why the checkout cannot be measured there, is explained in the guide How to measure website speed with PageSpeed Insights.

A store needs one more check. Open a product in a private Chrome window, press F12, choose the Network tab and reload. Click the first row, the page itself, and in the Timing tab look at the Waiting row, which shows the time to first byte (TTFB). Then add a product to the cart and repeat. If the second time is much longer, pages for shoppers with a cart are not coming from the cache.

The cart and session get in the way of the cache

A page cache works because every visitor sees the same thing. In a store that stops being true as soon as someone adds a product to the cart. WooCommerce then sets the cookies woocommerce_items_in_cart, woocommerce_cart_hash and wp_woocommerce_session_ so it knows which cart is theirs. The WooCommerce documentation says the Cart, Checkout and My Account pages must stay out of the cache, and lists these cookies as ones you can exclude from caching. How many pages bypass the cache after that depends on your cache plugin or server, so check what yours does.

The second part is the cart fragments script, which refreshes the mini cart at the top of the page. It sends the server a separate POST request, get_refreshed_fragments, which the page cache does not serve. Since WooCommerce 7.8 the script loads only when the Cart widget is on the page, but it still loads if the theme has a mini cart built into its code or another plugin depends on it. To check, type fragments into the filter box of the Network tab and reload. If you see get_refreshed_fragments, the script is running.

WooCommerce recommends the Mini-Cart block, which does not use this script. If the mini cart is part of a classic theme's code, update the theme or ask its developer. Do not switch the script off everywhere with code if your mini cart relies on it, because the mini cart will stop updating. And check that the cache excludes only Cart, Checkout and My Account, not the whole store. Some shopper requests will always bypass the cache, which is why the speed of PHP and the database (causes 3, 5 and 7) matters more for a store than for an ordinary site.

A heavy theme or page builder

Many store themes come with sliders, mega menus, quick product views, wishlists and a builder of their own. Every feature adds styles and scripts, sometimes on every page, even if you never use it. Page builders such as Elementor also add nested wrappers to the HTML, which means more work for the browser. How that happens and what you can do about it is covered in the guide Why Elementor slows down your site and what you can do.

To see how much the theme weighs, make a copy of the store and briefly switch it to Storefront or a default WordPress theme. Measure the same pages. If the difference is large, the weight is in the theme. In PageSpeed Insights, also look at the Render-blocking requests and Optimize DOM size insights.

Switch off the theme features you do not use, and remove the slider and video from the first mobile screen if you can do without them. If the theme stays heavy, replace it with a light one, on a copy and with a check of every page and the whole checkout.

Too many plugins and slow database queries

A store usually has more plugins than an ordinary site, for couriers, payments, invoices, reviews and marketing. Each adds code and database queries, and over time the database also collects things nobody uses. Check four things.

  • Which plugins run the most queries. Install Query Monitor for a while and open a slow page while logged in as an administrator. It groups database queries by plugin and theme and flags the slow and duplicate ones. Switch it off when you are done.
  • Autoloaded options. WordPress loads some plugin settings on every page load. Since version 6.6, Site Health (Tools, Site Health) checks them and shows "Autoloaded options could affect performance" when their total size exceeds 800 KB. They can include settings from plugins you deleted long ago. Cleaning them up is a job for someone who knows what they are deleting, because removing the wrong option can break a plugin.
  • Leftover tables and temporary data. WooCommerce, Status shows the size of every table in its Database section. Tables named after plugins that are no longer installed were most likely left behind by them. Delete them only after a backup, and only if you are sure whose they are. Under WooCommerce, Status, Tools, the Clear expired transients button removes expired temporary data.
  • Where orders are stored. Since WooCommerce 8.2, released in October 2023, new stores keep orders in dedicated tables, High-Performance Order Storage (HPOS). Older stores may still keep them in the WordPress posts tables, alongside products and pages. According to the WooCommerce documentation, dedicated tables mean fewer read and write operations and fewer busy tables. Check under WooCommerce, Settings, Advanced, Features.

Switching to HPOS takes two steps. You turn on Enable compatibility mode (synchronizes orders to the posts table), wait for the background sync to finish and then switch to High-Performance Order Storage. If a plugin is not compatible, WooCommerce blocks the switch and tells you which one. Test on a copy first, and while synchronisation is on, switching back is instant.

Unoptimised product images

In a store, images are everywhere. On a product page the main image is usually the largest element in the first screen, so it sets the LCP. Category pages hold dozens of thumbnails, and galleries with zoom and a lightbox load the large versions as well.

WooCommerce uses three image sizes. The large one is for the product page, the medium one for categories, and the thumbnail for the cart and the gallery. With a classic theme you set them under Appearance, Customize, WooCommerce, Product Images, and with a block theme under Appearance, Editor, in the relevant template. Uploaded images are resized to these values.

The problem is often the originals. A photo from a phone or a supplier can be several thousand pixels wide and several megabytes in size. WooCommerce recommends an original of at least 800 by 800 pixels for most themes, so images do not look blurry. You only need more if your theme displays images larger than that.

To find the problem images, look at the Improve image delivery and LCP request discovery insights in PageSpeed Insights for a product and a category. The second one shows whether the main image is discovered late or lazy loaded by mistake.

Shrink the originals to a sensible size and upload them again, or use a plugin that optimises them and converts them to WebP. If you change the sizes in the settings, run Regenerate shop thumbnails under WooCommerce, Status, Tools, so the old thumbnails are recreated too. How WebP and lazy loading work in WordPress is covered in the speed guide.

Slow hosting or an old PHP version

The cart, checkout and account pages never come from the cache. PHP and the database build them on every load, which is why hosting shows up more in a store than in an ordinary site.

Check the versions under WooCommerce, Status, where you will find PHP version, Database version and WP Memory Limit, and compare them with WooCommerce's recommendations for version 10.8 and later.

ItemWooCommerce recommendation
PHP8.3 or newer
DatabaseMySQL 8.0 or newer, or MariaDB 10.6 or newer
WordPress memoryat least 256 MB

WooCommerce still works with PHP 7.4 and MySQL 5.6, but its documentation warns that these versions have reached end of life and may expose the site to vulnerabilities. Watch out for PHP 8.2 as well, which according to php.net receives security fixes only until 31 December 2026. How to change the version in cPanel without breaking the site is covered in a separate guide.

If the versions are fine but the time to first byte stays high, look at the hosting itself. Useful signals are the real-visitor TTFB in PageSpeed Insights, the Document request latency insight and the cart check from the start of this guide. If these numbers are poor under normal traffic and the store throws errors during campaigns, it needs more CPU and memory or a server of its own, which is what we offer with cloud infrastructure.

Third-party scripts, pixels, chat and reviews

Ad pixels, analytics scripts, chat, review widgets and social buttons all come from other companies' servers. According to web.dev, such scripts add requests, keep the browser's main thread busy and can delay rendering. On a phone this shows mostly in TBT and INP.

Open the Third parties insight in PageSpeed Insights. It lists the external providers and how much each one weighs. Also check Google Tag Manager for tags from campaigns that ended long ago.

Remove every script that does not earn its place, as web.dev also advises. For those that stay, ask your developer to load them with async or defer, unless they are needed to render the page. Chat is a good candidate for a facade, a static button that looks like the chat and loads the real script only after a click. The Chrome documentation gives chat widgets and videos as typical examples and warns that some of their features then work only after the click.

Scripts added after launch also lower the PageSpeed Insights score. That is why, on the sites we build, we review new scripts together with the client before they go in.

Search and filters on a large catalogue without an object cache

The WooCommerce search form uses the standard WordPress search. It looks for each word in the title, excerpt and content of the products with a query of the form LIKE '%word%'. According to the MySQL documentation, an index cannot help when the search text starts with a wildcard, so on a large catalogue the database scans many rows for every search.

Filters by colour, size or price create a separate address for every combination. There are too many combinations to keep in the cache, so each one is built from scratch. Google warns that crawlers visit large numbers of such addresses and that this costs sites a lot of computing resources.

WordPress has an object cache that keeps database results, but by default it only lives for as long as one page takes to load. A persistent object cache with Redis or Memcached keeps them for the next visits too, and saves repeated database queries. Site Health itself recommends a persistent object cache ("You should use a persistent object cache") once one of the main tables has a thousand rows or more, for example the posts table, where products live too.

You can see whether you have a persistent object cache under WooCommerce, Status, in the Dropin Plugins section. If object-cache.php is listed there, it is on. If not, ask your host whether they offer Redis or Memcached. A plugin such as Redis Object Cache connects WordPress to Redis, but Redis itself has to run on the server.

On a very large catalogue, search moves to a separate index built for the purpose. Filter addresses that should not be indexed can be blocked for crawlers in robots.txt, as Google describes, but decide that with whoever handles your SEO, because some filtered pages bring in visits.

When tuning stops paying off

If you have gone through all seven causes and the store is still slow on mobile, or it is fast on quiet days but buckles during campaigns and sales, you have probably reached the limit of the classic model. In it, every page that is not in the cache goes through PHP and the database, which also serve the cart and the admin.

That is when it makes sense to rebuild the store as headless. Shoppers get a fast storefront built with Next.js, and WooCommerce stays in charge of products and orders. In our model, Speedy and Econt are right in the checkout, orders go through a queue so that no order is lost even when WooCommerce does not answer, and Kubernetes adds capacity when traffic grows. We aim for 90+ for speed and 100 for SEO in PageSpeed Insights.

With a rebuild of an existing store, products, orders and customer accounts stay in WooCommerce, you run the store from the same admin, and old addresses redirect to the new ones. How to decide whether you need one is covered in our guide on classic WooCommerce versus a headless store, and the rebuild itself in how a WooCommerce headless rebuild works.

Checklist

  • The home page, a category, a product and the cart are measured on mobile, and TTFB is compared with and without a cart.
  • The cache excludes only Cart, Checkout and My Account, and cart fragments loads only where it is needed.
  • The theme has been compared with a light theme on a copy of the store.
  • Unneeded plugins are deleted after a backup, and Site Health shows no autoloaded options issue.
  • Orders are stored in the HPOS tables.
  • Image originals are a sensible size, and the thumbnails have been regenerated.
  • PHP is 8.3 or newer, and memory is at least 256 MB.
  • Every third-party script has a reason to be in the store.
  • A large catalogue has a persistent object cache.

Do you have to do this yourself?

Some of these checks take minutes, such as the versions under WooCommerce, Status or the warning in Site Health. The bigger steps, such as moving to HPOS, changing the theme or cleaning up the database, are better done on a copy of the store by someone who has done them before. With speed optimisation we tune the cache, Redis, PHP and the database for the store's load, measure before and after, and show you the difference in numbers. If the store has reached the limit of the classic model, take a look at the headless rebuild.

Frequently asked questions

Why is my WooCommerce store slow?

A slow WooCommerce store rarely has just one cause. The most common are the cart and session getting in the way of the cache, a heavy theme or page builder, too many plugins and slow database queries, unoptimised product images, slow hosting or an old PHP version, third-party scripts, and search and filters on a large catalogue without a persistent object cache. Start by measuring the home page, one category, one product and the cart in PageSpeed Insights on mobile.

Why does the store slow down once a product is in the cart?

As soon as someone adds a product to the cart, WooCommerce sets the cookies woocommerce_items_in_cart, woocommerce_cart_hash and wp_woocommerce_session_ to know which cart is theirs, and how many pages bypass the cache after that depends on your cache plugin or server. Use the Network tab in Chrome to check a product's time to first byte before and after adding to the cart. If the second is much longer, pages for shoppers with a cart are not coming from the cache.

What is cart fragments in WooCommerce and does it slow the site?

It is the script that refreshes the mini cart at the top of the page with a separate POST request, get_refreshed_fragments, which the page cache does not serve. Since WooCommerce 7.8 it loads only when the Cart widget is on the page, but it also loads if the theme has a built-in mini cart or another plugin depends on it. WooCommerce recommends the Mini-Cart block, which does not use this script.

What is HPOS and should I switch to it?

High-Performance Order Storage (HPOS) keeps orders in dedicated tables instead of the WordPress posts tables alongside products and pages. According to the WooCommerce documentation this means fewer read and write operations and fewer busy tables, and new stores have used it since WooCommerce 8.2. Check under WooCommerce, Settings, Advanced, Features, and switch with compatibility mode first, testing on a copy of the store.

How large should WooCommerce product images be?

WooCommerce recommends an original of at least 800 by 800 pixels for most themes so images do not look blurry, and you need more only if your theme displays images larger than that. A photo from a phone or a supplier is often several thousand pixels wide and several megabytes in size. Shrink the originals and upload them again, and if you change the sizes in the settings, run Regenerate shop thumbnails under WooCommerce, Status, Tools.

Which PHP and database versions does WooCommerce recommend?

For version 10.8 and later, WooCommerce recommends PHP 8.3 or newer, MySQL 8.0 or newer or MariaDB 10.6 or newer, and at least 256 MB of WordPress memory. The versions are shown under WooCommerce, Status. WooCommerce still works with PHP 7.4 and MySQL 5.6, but its documentation warns that these versions have reached end of life.

Do I need Redis for a WooCommerce store?

On a large catalogue with search and filters, a persistent object cache with Redis or Memcached saves repeated database queries. Site Health itself recommends one once a main table, such as the posts table where products live too, has a thousand rows or more. You can see whether you have one under WooCommerce, Status, in the Dropin Plugins section, and if object-cache.php is not listed, ask your host whether they offer Redis or Memcached.

When does tuning stop helping a slow store?

When, after all seven causes, the store is still slow on mobile, or it is fast on quiet days but buckles during campaigns and sales. You have then probably reached the limit of the classic model, where every page not in the cache goes through PHP and the database. That is when a headless rebuild makes sense, with a Next.js storefront while products, orders and customer accounts stay in WooCommerce.

Sources

# TagsWooCommerceSpeed