A paper shopping cart full of shopping bags speeding out of a small shop

If you want to know how to speed up WooCommerce, start with the pages that make you money: product, cart and checkout. Those are the pages where waiting costs you orders.

Most slow WooCommerce stores share the same handful of problems. Product photos are too heavy, the hosting wasn't built for a store, the database has never been cleaned and there are too many plugins. If that sounds like your store, the good news is that the fixes are well understood.

This is the order I work through, step by step, so you can do the same. The goal isn't one lab score. It's to find the bottleneck, make one safe change at a time and confirm that product, cart and checkout pages still work after each one.

Measure before you change anything

Record a baseline

Test the home page, one category page, one product page, the cart and checkout.

Protect the store

Take a backup and use a staging copy for PHP, plugin, cache and database changes.

Change one layer

Test image, hosting, caching, plugin and database changes one at a time.

Verify the buying path

Add a product, change the quantity, calculate shipping, try a coupon and complete a test order.

Why WooCommerce Is Slower Than Regular WordPress

A WooCommerce store does a lot more work on every page load than a blog or a brochure site. That's why stores slow down in ways regular WordPress sites don't.

Comparison of the work behind a normal WordPress page and a WooCommerce product page with price, stock, variations and cart data
A product page asks the server for far more than a blog post does.

A standard WordPress page pulls some content from the database, renders a template and sends it to the browser. A WooCommerce product page does all of that, plus:

  • Looks up product data, pricing, stock status and variation attributes
  • Loads a product gallery with several image sizes and lightbox scripts
  • Keeps the mini cart in the header up to date, if your theme shows one
  • Loads extra CSS and JavaScript for the storefront, the cart widget and checkout

Cart and checkout pages add shipping, tax and payment work on top. Multiply all of that by a few hundred products with variations, and you can see why a store slows down without deliberate work.

Step 1: Fix Your Product Image Pipeline

Images are usually the heaviest thing on a store's pages. Product photos are big, there are a lot of them, and WooCommerce makes several sizes of each one for thumbnails, galleries and product pages.

Convert Everything to WebP

If your product images are still JPEG or PNG, you're serving bigger files than you need to. Google's WebP page puts lossy WebP images at 25 to 34% smaller than comparable JPEGs at the same quality. Every major browser supports it.

Bar chart: WebP images are 25 to 34 percent smaller than JPEG at the same quality, according to Google
Same picture, smaller file. Google measured lossy WebP at 25 to 34% smaller than JPEG. Source: Google for Developers, WebP
  • JPEG: 100 (relative file size)
  • Lossy WebP: 66 to 75 (25 to 34% smaller)

A plugin like ShortPixel or Imagify can convert your existing images to WebP and serve the right format to each browser. Set a maximum image size that matches the largest size your theme shows. There's no reason to upload a 4,000 pixel photo when the product gallery displays it at 800.

Use a CDN for Media Files

A CDN (content delivery network) keeps copies of your images on servers in many places. A shopper in Lexington gets images from a server nearby instead of waiting on your one origin server. A shopper in California gets them from a West Coast server.

If you're on a managed host or already use Cloudflare, you may have a CDN available. Check that it's actually turned on for your media files. Having it in your plan doesn't mean it's switched on.

Lazy Load Product Images

A shop page might show 20 or 30 products. Without lazy loading, the browser downloads every product image right away, even the ones nobody has scrolled to yet. Lazy loading tells the browser to load images as they come into view.

WordPress has lazy-loaded images by default since version 5.5. Some theme and gallery templates skip it, though. Check that your product images carry loading="lazy", or use a plugin like Perfmatters to handle it.

Leave the main product photo at the top alone. It should load right away.

Step 2: Enable Redis Object Caching

On a store, this is often the biggest server-side win, and most store owners have never heard of it.

What Redis does: Every product page load runs a lot of database queries for product info, prices, variations, stock and related products. Redis keeps the results of those queries in the server's memory, so the next request doesn't have to ask the database again. The server keeps a cheat sheet instead of looking everything up from scratch.

Cart, checkout and account pages can't use full page caching, because they're different for every shopper. Object caching still helps them.

On a database-heavy store it can cut Time to First Byte (TTFB) a lot, with no changes to the store's code or content. Measure TTFB before and after so you know what it did.

Many managed WordPress hosts offer Redis, sometimes as an add-on. Once your host has it running, you usually install the Redis Object Cache plugin and click Enable.

If your host doesn't offer Redis at all, that's a sign the hosting may not be built for a store. Bargain shared hosting struggles with a store's database load. My article on common website mistakes covers cheap hosting, and it matters even more for an online store.

Step 3: Tame the Cart Fragments

Cart fragments are the requests that keep the little cart icon in your header up to date without a page refresh. On older setups, WooCommerce sent one on every page load, even for visitors with nothing in their cart.

Diagram of WooCommerce sending a cart request on every page load compared with only on shop pages when the cart has items
Since WooCommerce 7.8 the script only loads with the Cart widget. A cart in the header can still put it on every page. Source: WooCommerce Developer Blog

Since WooCommerce 7.8, the cart fragments script only loads when the page shows the Cart widget. That helps. But many themes put that widget in the header, so the request can still fire on every page of your site.

To check, open your browser's Network tab, reload a page and look for a request with get_refreshed_fragments in it.

If it's firing everywhere, you have a few options:

  • Turn cart fragments off where they aren't needed. Someone reading your About page or your blog doesn't need a live cart count. Perfmatters can do this, or a developer can remove the script from those pages.
  • Load it after the page. Let the cart update after the page has shown. This doesn't cut the total work, but the shopper sees the page sooner.
  • Only ask when there's a cart. Some performance plugins check whether the shopper has anything in the cart first. No items, no request.

It's a small change. It stops an extra server request on every page that doesn't need one.

Step 4: Limit Product Variations

If you sell a t-shirt in 5 colors and 6 sizes, WooCommerce creates 30 variations. Each one is its own database entry with its own price, stock status and attributes.

Grid of five colors by six sizes showing how one T-shirt becomes 30 product variations
Five colors and six sizes already make 30 variations. That's also WooCommerce's default cutoff for loading every variation into the page. Source: WooCommerce docs

Options multiply fast. A product with 3 attributes and 10 options each can mean 1,000 variations.

By default, WooCommerce builds the data for every variation into the product page when there are 30 or fewer. That's what lets the dropdowns update right away.

Above 30, it looks up the matching variation after the shopper picks. Some themes and swatch plugins raise that limit, and then a big product can carry a lot of variation data before anyone picks a size.

Practical fix: If your theme or a plugin raised the woocommerce_ajax_variation_threshold filter, check whether it needs to be that high. Test any change on a staging copy first, because themes and swatch plugins can depend on it.

Also, audit your variations. Do you actually need every combination?

If nobody buys a purple XXS, remove it. Fewer variations means less data to look up and less JavaScript to run.

Step 5: Clean Up the Database

Stores build up database clutter faster than regular WordPress sites. Orders, customer sessions, transients and page revisions all add up.

Take a backup before any cleanup. Orders and customer data aren't the place to experiment.

Delete Old Transients

Transients are temporary data that WordPress and WooCommerce store in the database, like cached prices and shipping rates. WordPress clears expired ones with a daily scheduled task, but only if WP-Cron actually runs.

When it doesn't, stale rows pile up. A cleanup plugin like WP-Optimize can clear them.

Limit Post Revisions

WordPress saves a revision every time you update a page or blog post. WooCommerce doesn't keep revisions for products by default, but the rest of your site does. Edit a page 20 times and you have 20 old copies in the database.

You can cap that with the WP_POST_REVISIONS setting in wp-config.php. Setting it to 3 keeps the last three. WordPress documents the setting here.

Clean Up WooCommerce Sessions

WooCommerce stores a session for shoppers who put something in the cart, and bots can create them too. On a busy store, that table can get large.

WooCommerce clears expired sessions on a schedule, which also depends on WP-Cron. If the table keeps growing, check that first.

On a store that's run for a year or two with no upkeep, cleanup can shrink the database a lot. When the database is leaner, queries get faster across the whole site.

WooCommerce Store Running Slow?

I'll audit your store, find the bottlenecks and give you a clear fix plan in priority order. No score promises and no guesswork.

Call (502) 305-4043

Step 6: Improve Your Hosting for WooCommerce

A lot of small stores run on cheap shared hosting. Then the owner wonders why the site drags at busy times and why checkout sometimes times out.

A store needs more from its server than a brochure site does. It runs PHP and queries the database on every uncached request, processes payments and tracks inventory. Shared hosting wasn't built for that.

What to look for in WooCommerce hosting:

  • PHP 8.3 or higher. That's in the official WooCommerce server recommendations, along with MySQL 8.0 or MariaDB 10.6 and a 256 MB WordPress memory limit. Check that your plugins and theme work with the new PHP version on staging before you change the live server.
  • Object caching (Redis or Memcached). See Step 2.
  • Server-level page caching that already knows to skip cart, checkout and account pages.
  • A CDN included, so you don't have to set one up separately.
  • A staging copy, so you can test changes without breaking the live store.

WP Engine, Kinsta and Cloudways are all solid options. For retail businesses running WooCommerce, pick a host that handles the cart and checkout cache exclusions for you.

Step 7: Minimize Plugin Bloat

Every plugin can add CSS, JavaScript and database queries. Some are necessary. Many aren't.

Go through your plugin list and ask three questions about each one.

Is it active? Is it needed? Is there a lighter option?

Common WooCommerce plugin bloat:

  • More than one SEO plugin (pick one, usually Yoast or Rank Math, and remove the rest)
  • Social sharing plugins that load scripts on every page, including product pages
  • Abandoned cart plugins that add tracking JavaScript to every page
  • Slider and page builder plugins that load their full framework on pages that don't use them
  • Analytics plugins when the standard GA4 tag would do

Removing what you don't need and swapping heavy plugins for lighter ones means fewer files for the browser to download. Check the Network tab before and after so you can see the difference.

Step 8: Enable Page Caching (the Right Way)

Page caching saves a finished HTML copy of a page, so the server doesn't rebuild it on every visit. It's standard for WordPress, but stores make it tricky. You can't cache pages that are different for each shopper, like the cart, checkout and My Account.

Most managed hosts handle those exclusions for you. If you run your own caching with a plugin like WP Rocket or W3 Total Cache, make sure those pages are excluded.

Cache these: the home page, shop page, product pages, category pages, blog posts and static pages.

Never cache these: cart, checkout, My Account and any page with a form that handles one shopper's data.

What Good Looks Like

Don't aim for a lab score. Aim for Google's thresholds on your real product, cart and checkout pages. Google counts a page as good when at least 75% of real visits hit these marks:

Loading (LCP): the main content shows in 2.5 seconds or less.

Responsiveness (INP): the page reacts to a tap or click in 200 milliseconds or less.

Layout shift (CLS): 0.1 or less, so buttons don't jump around while the page loads.

Server response (TTFB): 0.8 seconds or less. It isn't a Core Web Vital, but Google's tools treat it as the "good" range. Google lists all four thresholds here.

Those are targets, not guarantees. Every store is different. But on a store, speed shows up in whether shoppers get through checkout, so it's worth measuring after every change.

Lou the mascot holding a shopping bag beside a cart full of boxes and a speed dial near the fast end
Shoppers rarely notice a fast store. They just keep shopping.

Where to Start

If your store is slow and you're not sure where to begin, here's the order I recommend:

  1. Run a PageSpeed test. Go to pagespeed.web.dev and test your home page and one product page. Note the real-user data and the issues it flags.
  2. Turn on Redis object caching. If your host offers it, it's usually quick, and it helps the pages you can't page-cache.
  3. Convert images to WebP. Install ShortPixel or Imagify and let it process your catalog.
  4. Check cart fragments. If the request fires on every page, turn it off where it isn't needed.
  5. Clean up the database. Back up first. Then clear expired transients, cap revisions and check the sessions table.
  6. Audit your plugins. Remove what you don't need. Replace heavy plugins with lighter ones.

Handle those six carefully and you'll have a cleaner store and a real before-and-after measurement. After that, ongoing website maintenance keeps updates, images and plugins from slowly bringing the problem back.

Stores make every weak layer more visible, because the buying path runs on dynamic pages. My WordPress speed guide covers the same steps for the rest of the site. If you want the quick diagnostic version, start with what to check first on a slow WordPress site.

If you'd rather hand it off, that's what I do. I'm based in Louisville and work with small businesses nationwide. When the cause isn't clear yet, the $250 Website Rescue diagnostic finds the bottleneck and gives you a written fix plan.