Skip to content
HelalStart a project

My WooCommerce store got slow as it grew. What do I fix first?

The store was quick when it was small. Now product and category pages hang on a phone, the admin crawls, and checkout slows to a stop on busy days.

The store was fast when it was small

When you launched, pages loaded quickly. Then the catalog grew to thousands of products, orders piled up, and plugins were added one by one. Now a category page takes seconds on a phone. Search in the admin hangs. The orders screen times out. On a busy evening, checkout slows down and some customers see an error.

Nothing broke on a single day, so it's hard to point at a cause. That is what makes this kind of slowness expensive: it grows quietly with the business, and the busiest days are the slowest.

Speed matters here in a plain way. A shopper waiting on a blank product page has time to go back to the search results. Paid traffic makes it sharper, because you pay for the click whether the page loads or not.

Field data first

Two kinds of numbers get mixed up:

  • Field data comes from real Chrome users through the Chrome UX Report. Search Console's Core Web Vitals report shows it, over 28 days, judged at the 75th percentile.
  • Lab data comes from Lighthouse: one simulated load. It is repeatable and good for finding causes, but it isn't what your customers felt.

I decide what to fix from field data and use the lab and the server to find out why. Google's guidance for Largest Contentful Paint is 2.5 seconds or less, Interaction to Next Paint 200 milliseconds or less, and Cumulative Layout Shift 0.1 or less.

Why it happens

The server takes longer for every page

Before the browser can do anything, the server builds the page. WooCommerce runs PHP and database queries on every uncached request. As the store grows, each of those costs more:

  • Uncached pages. Cart, checkout and account pages can't be cached for everyone, and logged-in customers usually bypass the page cache entirely. A store with many returning customers serves a lot of uncached pages.
  • Database queries. Product queries with many attributes, layered navigation filters, related products and "recently viewed" widgets get slower as the tables grow. Without indexes that match the queries, the database scans more rows every month.
  • Autoloaded options. WordPress loads every autoloaded row in wp_options on every request. Plugins leave large rows behind, including ones from plugins removed years ago.
  • No object cache. Without Redis or a similar object cache, WordPress repeats the same queries on every request.
  • Orders in the posts tables. Before HPOS, orders live in wp_posts and wp_postmeta alongside products and pages. With a large order history, order queries and the admin slow down, and they compete with the storefront.

PHP workers run out

Each uncached request holds a PHP worker until it finishes. Hosting plans give a fixed number. When requests take longer, workers stay busy longer, and new requests queue. That is why a store can feel fine at noon and fall over in the evening: the work per request didn't change, but the queue did.

Cart fragments and admin-ajax

WooCommerce's cart fragments script calls ?wc-ajax=get_refreshed_fragments to update the mini cart. That request skips the page cache and runs PHP. Many themes still load it on every page, so a fully cached page still costs a worker per view. Plugins that poll admin-ajax.php for live stock, notifications or chat add more of the same.

The front end waits too

Even with a fast server, the page can feel slow:

  • The main product image is lazy-loaded, oversized or set as a CSS background, so the browser finds it late.
  • Every plugin adds its stylesheet and script to every page.
  • Fonts in several weights load from a third-party host with no font-display rule.
  • Marketing tags stack up: the same pixel from a plugin and from Tag Manager, two copies of the GA4 tag, a chat widget that loads its full app on every view.

On a phone, each of these competes for a weak CPU and a slow network.

What fixing it involves

I work in a fixed order. Preloading an image is pointless if the server takes three seconds to send the HTML.

1. Measure

I pull field data for the key templates: home, category, product, cart, checkout. I run lab tests on a throttled mobile profile and record a trace for each. On the server, I profile slow requests with query logging and an application profiler, so each slow page gets a named cause: a plugin hook, a query, a remote API call.

2. Fix caching

Full-page caching for anonymous visitors, at the server or at the edge with Cloudflare, with cart, checkout and account pages excluded. An object cache. Cart fragments loaded only where a mini cart needs them. I check that a cached page never shows another customer's cart. A fast page that shows the wrong cart is worse than a slow one.

3. Fix the database

I clean up autoloaded options, remove tables and rows from plugins that are gone, add indexes where the profiler shows a scan, and replace slow plugin queries where that's the cause. For stores with a large order history I plan the move to HPOS: compatibility check on staging, sync mode, then the switch.

4. Size the server

With the slow code fixed, I look at the server again: enough PHP workers for the traffic, enough memory for the database and the object cache, current PHP and MySQL or MariaDB versions. If the host is the limit, I say so plainly and plan the move. See migrating off a slow host.

5. Fix the largest element and the scripts

Remove lazy-loading from the above-the-fold image, add fetchpriority="high", serve a correctly sized WebP or AVIF, and reserve its space. Remove duplicate pixels so each tag fires once, from one place. Defer what stays, and stop plugins from loading assets on pages where they do nothing. Fewer font weights, self-hosted and subset. I check tracking still works afterwards.

6. Guard against regressions

Speed gets lost one plugin at a time. I set a performance budget for each key template, monitor field data and server response time, and test plugin and theme updates on staging against the budget before they go live.

If the slowness shows up mainly when campaigns run, read scaling a store for ad traffic. This is the core of my performance engineering work.

Related service: Performance engineering

01 / Proof

Where I've done this

I rebuilt the loading path of an Israeli jewelry store with a Hebrew, right-to-left storefront: LCP and preload fixes, font and script cleanup, duplicate pixel removal and server-side profiling.

Israeli jewelry store (Hebrew, right-to-left)

Live

Performance overhaul

Problem
Slow pages on mobile, heavy tracking scripts and a late-loading hero.
What I built
LCP and preload fixes, font and script cleanup, duplicate pixel removal, server-side profiling.
Outcome
Live in production; the hero image loads first and each tracking pixel fires once.
Stack
  • WordPress
  • WooCommerce
  • Cloudflare

02 / Questions

Questions owners ask

My Lighthouse score is low but Search Console says my pages are fine. Which one is right?
Search Console is closer to what your shoppers felt. It shows field data from real Chrome users over the last 28 days. Lighthouse runs one simulated load on a throttled phone, which is useful for finding causes but is not a measure of your store. I use Lighthouse to debug and field data to decide what is worth fixing.
Will more hosting resources fix it?
Sometimes, for a while. If PHP workers are queuing or the database runs out of memory, more resources help at once. But a slow query or an uncached page gets slower again as the store grows, just on a bigger bill. I profile first, so you know whether the fix is the server, the code or both.
Should I switch to HPOS?
For a store with many orders, usually yes. High-Performance Order Storage moves orders out of the posts tables into their own tables, which makes order queries and the admin faster. It needs every plugin that touches orders to support it, so I check compatibility on a staging copy and run in sync mode before switching over.
Do I need a rebuild or a headless front end?
Usually not. Most slow stores get much faster with caching, query fixes and a cleaner script load, without touching the design. A headless front end makes sense when the theme layer itself is the limit. I tell you which case you're in after measuring, not before.

Want me to look at your setup?

I review your site before a short discovery call and come with the questions and risks I see.

Start a projectGet the free checklist