Performance15 min readPublished: 20 Jan 2025Updated: 4 Jul 2026

How to Speed Up WooCommerce: A Complete Guide

WooCommerce is slow because carts and checkout can't be cached. Here is how to fix it: page caching rules, object caching, database cleanup and PHP workers.

G7Cloud Engineering
Platform team
Share:
Abstract diagram of dynamic cart traffic separating from cached page traffic
  • WooCommerce is slow mainly because cart, checkout and account pages cannot be cached and run full PHP plus database queries on every request.
  • Page-cache the catalogue aggressively, exclude cart and checkout by cookie, and add a persistent object cache so PHP stops re-asking the database the same questions.
  • Database bloat (expired transients, autoloaded options, session and Action Scheduler tables) quietly slows every uncached request; clean it monthly with WP-CLI.
  • Checkout spikes exhaust PHP workers when your store shares resources with other sites; a dedicated container removes that contention.
  • Diagnose before you optimise: measure TTFB, watch admin-ajax cart-fragments, and use Query Monitor to find the slow queries and heavy plugins.

Why is my WooCommerce store so slow?

To speed up WooCommerce, page-cache the catalogue but exclude cart, checkout and account pages, add a persistent object cache like Redis, clean out database bloat (expired transients and session rows), audit heavy plugins, and run each store on its own PHP workers. Together these fix the four causes: uncacheable pages, repeated queries, table bloat and resource contention.

A standard WordPress blog can serve almost every visitor a cached HTML page, so PHP barely runs. WooCommerce cannot. Cart contents, the logged-in account area and checkout are unique per visitor, so a large share of your traffic hits PHP and the database directly. On top of that, WooCommerce adds product, order, session and inventory data that turn one page load into hundreds of queries.

So the slowness is rarely one thing. It is usually a stack: pages that skip the cache, a database that has quietly bloated, a plugin or two loading assets on every page, and a hosting plan where a traffic spike runs you out of PHP workers at the worst moment. This guide works through each cause, with the WooCommerce-specific detail and the commands to fix it.

100s
queries per uncached page

A busy WooCommerce cart or checkout can issue hundreds of database queries per request, versus a handful for a cached blog page.

What makes WooCommerce harder to speed up than a normal WordPress site?

WooCommerce is harder because a large part of its traffic is personal and therefore uncacheable. Cart, checkout, My Account and any page showing basket contents change per visitor, so they must run PHP and hit the database on every request. A brochure WordPress site can serve 95% of requests from a static cache; a busy store often cannot cache the pages that matter most for revenue.

WooCommerce also stores far more data. Every order writes rows across several tables. Every visitor, logged in or not, gets a session. Products carry variations, attributes and metadata. Inventory, coupons and tax rules add more lookups. The result is a database that grows quickly and query counts that climb with catalogue size and order history.

The practical consequence: you cannot speed up a store by turning on a caching plugin and walking away. You need caching rules that respect the cart, a way to reduce repeated database work, ongoing database housekeeping, and enough PHP capacity to absorb checkout spikes. Miss any one of those and the store still feels slow under real load, even if your homepage scores well in a synthetic test.

Page typeCacheable?Why
Homepage, category, productYes, aggressivelySame HTML for every anonymous visitor
CartNoContents are unique per visitor
CheckoutNoOrder data, payment, per-visitor session
My AccountNoLogged-in, personal order history
Blog posts, static pagesYesSame for everyone, no personal state

The rule of thumb: cache anything identical for all anonymous visitors; never cache anything personal.

How do I cache WooCommerce without breaking the cart and checkout?

Cache the catalogue aggressively and exclude the personal pages by URL and by cookie. Configure your page cache to never serve cart, checkout and account pages, and to bypass the cache entirely for any request carrying a WooCommerce cart or session cookie. Then test with a real item in the basket, because most broken-cart bugs come from a cache that ignores those cookies.

The mechanism matters. When a visitor adds to cart, WooCommerce sets cookies such as woocommerce_items_in_cart and woocommerce_cart_hash, plus a session cookie like wp_woocommerce_session_. Your cache must treat the presence of those cookies as a signal to bypass. If it does not, one shopper can be served another shopper's cached cart, or a stale empty cart is served to someone who just added an item. That is the classic exclusion leak, and it is worse than being slow.

Cart fragments can flood admin-ajax

WooCommerce keeps the little cart total in your header live using an AJAX call to admin-ajax.php (wc-ajax=get_refreshed_fragments). On an uncached theme this can fire on every page load for every visitor, quietly generating a large share of your PHP traffic. If your slow requests are dominated by admin-ajax, cart fragments are the likely cause. Limit fragments to pages where the cart is actually shown, or cache the fragment response briefly.

For the pages you genuinely cannot cache, the goal shifts from avoiding PHP to making each PHP request cheap. That is where object caching comes in, covered next. But get the exclusions right first: a fast checkout that occasionally shows the wrong cart will cost you far more than a slow one.

Pro Tip

After changing cache rules, test in an incognito window: browse the catalogue (should be cached and fast), add an item, then reload the cart and checkout. If the basket count is ever wrong across a page load, your cookie-based exclusion is leaking.

Does object caching (Redis) speed up WooCommerce?

Yes, a persistent object cache is one of the biggest wins for a busy WooCommerce store. WooCommerce makes the same database lookups over and over within a single request and across requests. A persistent object cache (Redis is the common choice) keeps those results in memory, so PHP stops asking the database the same questions. On cart and checkout pages, which you cannot page-cache, this is often the single largest speed-up available.

Without a persistent object cache, WordPress rebuilds its object cache from scratch on every request. With one, expensive results (option lookups, product data, term relationships) survive between requests. For a store doing real traffic this can cut database load sharply and drop time-to-first-byte on the dynamic pages that never see the page cache.

How this works on G7Cloud

Every store on G7Cloud runs in its own dedicated container with its own database, so there are no shared tables and no noisy neighbours competing for the same query cache. That isolation is what makes a persistent object cache reliable: the memory it uses is yours, not shared with fifty other sites. See WooCommerce hosting for how each store is provisioned.

Object caching is not a cure for a badly bloated database or a plugin running a slow query on every page. It hides repeated work; it does not fix work that should not happen at all. Pair it with the database cleanup and plugin audit below, and measure before and after so you know the object cache is actually being hit.

How does database bloat slow WooCommerce down, and how do I clean it up?

Database bloat slows WooCommerce because every uncached request reads from tables that have grown far larger than they need to be. The usual culprits are expired transients and autoloaded rows in wp_options, an ever-growing WooCommerce sessions table, Action Scheduler logs, post revisions, and orphaned rows in wp_postmeta. Clean these regularly and product queries, cart operations and the admin all get faster.

The most common quiet killer is autoloaded data in wp_options. Every request loads all rows marked autoload = yes into memory. Plugins that dump large serialised blobs there add weight to every single page load, cached or not. Expired transients pile up in the same table. On stores that take a lot of traffic, the wp_woocommerce_sessions table and Action Scheduler tables (wp_actionscheduler_actions, wp_actionscheduler_logs) can grow to hundreds of thousands of rows if nothing prunes them.

SymptomLikely causeFix
Slow admin and slow every pageLarge autoloaded wp_optionsFind big autoload rows, remove or set autoload = no
Queries reference _transient_%Expired transients not prunedwp transient delete --expired
Huge wp_woocommerce_sessionsOld guest sessions not clearedLet WooCommerce cleanup run, or prune expired sessions
Action Scheduler tables massiveCompleted/failed actions not purgedPrune completed actions on a schedule
wp_postmeta enormousOrphaned meta and old revisionsClean orphaned meta, limit post revisions

Map the symptom to the table, then run the targeted cleanup rather than a blanket optimise.

WP-CLI makes the routine cleanup a one-liner. wp transient delete --expired clears stale transients. wp db query lets you inspect the biggest autoloaded options. wp db optimize rebuilds fragmented tables. Set a monthly job for the safe ones and review the heavy tables by hand a few times a year. On G7Cloud each store has its own MariaDB database with WP-CLI and phpMyAdmin available, so this housekeeping never touches anyone else's data.

Check autoload weight first

Run: wp option list --autoload=on --format=count to see how many rows load on every request, and inspect the largest with a query ordered by LENGTH(option_value). If autoloaded data is more than roughly 1 MB, that alone is worth fixing before you touch anything else, because it taxes every uncached page.

How many plugins is too many for a WooCommerce store?

There is no magic number; what matters is what each plugin does on every request. Ten well-behaved plugins can be faster than three that each run a database query and load their own CSS and JavaScript on every page. The real question is not how many plugins you have, but how much work they do per page load and which of them run on the front end when they only need to run in the admin.

WooCommerce extensions are frequent offenders because many load assets site-wide when they are only needed on a single template. A currency switcher, a wishlist, a reviews add-on and a page builder can each enqueue scripts on every page, so a product listing pulls in code it never uses. The cost shows up as extra queries, larger pages and more render-blocking assets, all of which hit the uncacheable pages hardest.

Audit with Query Monitor. It shows you, per page, how many queries ran, which plugin or theme fired them, how long each took, and which scripts and styles loaded. Sort by time, find the plugin adding the most query time on your key templates, and decide whether it earns its place. For assets, dequeue plugin CSS and JavaScript on templates that do not need them, so the wishlist script no longer loads on the checkout.

Every page
is where badly-scoped plugins load

The problem is not plugin count; it is plugins that load front-end assets and run queries on templates that never use them.

This is the same principle we cover in why WordPress performance shouldn't depend on plugins: reach for a plugin when it earns its keep, and remove the ones whose cost you cannot justify with a measurement. A leaner plugin set is usually the cheapest speed-up on a mature store.

How do I stop hosting resource limits throttling my checkout?

Give your store enough PHP workers and its own resources so a traffic spike cannot exhaust them. A PHP worker is a process that handles one request at a time. Cached pages barely touch them, but every cart, checkout and account request occupies a worker for the whole request. When more uncacheable requests arrive than you have workers, the rest queue, and shoppers see a checkout that hangs or times out.

This is why a WooCommerce store feels fine on a normal day and falls over during a sale. A marketing email or an ad campaign sends a burst of shoppers straight to cart and checkout: exactly the pages the page cache cannot help with. Each one holds a worker. If you are on a plan with a low worker count, or sharing capacity with other sites, the queue builds and response times climb precisely when every conversion counts.

Shared hosting hides the ceiling

On shared plans the PHP worker limit and CPU are often invisible until you hit them, and a neighbour's traffic spike can consume the headroom you were counting on. The failure mode is a slow or failing checkout with no obvious cause on your own site. A dedicated container removes that variable: your workers and CPU are yours.

On G7Cloud every store runs in its own dedicated container, so a checkout spike on another shop is not your problem, and the resources you provision are the resources you get. Combine that with the caching and database work above and the goal is simple: keep as much traffic as possible on the page cache, make the uncacheable requests cheap with object caching, and have enough workers left to absorb the checkout burst. Our monitoring checks each site every minute so a resource problem alerts you rather than a customer.

What is a practical WooCommerce speed checklist?

Work in this order: measure first, then fix the biggest cause you find. Optimising blind wastes effort on things that were never slow. Start by diagnosing where the time goes, then apply caching, object caching, database cleanup, a plugin audit and enough PHP capacity, re-measuring after each change so you know what actually moved the number.

StepWhat to doHow to check it worked
1. MeasureRecord TTFB on home, product, cart and checkout; open Query MonitorYou know your slowest page and its query count
2. Page cacheCache catalogue, exclude cart/checkout/account by URL and cookieCatalogue TTFB drops; cart shows correct items in incognito
3. Cart fragmentsStop get_refreshed_fragments firing site-wideadmin-ajax traffic falls sharply
4. Object cacheEnable a persistent object cache (Redis)Cart/checkout TTFB and query counts drop
5. DatabasePrune transients, sessions, Action Scheduler; trim autoloadAutoload under ~1 MB; sessions table small
6. PluginsDequeue unused assets; remove plugins that don't earn their placeFewer queries and assets on key templates
7. CapacityEnsure enough PHP workers and dedicated resourcesCheckout holds up under a load test / real sale

A repeatable order of operations. Re-measure TTFB after each step so you can attribute the gain.

Measurement is the step most people skip. Watch time-to-first-byte on the four page types above, because TTFB is where server-side slowness shows up before anything renders. Use Query Monitor to see the query count and the heaviest plugins per template. If your logs show a flood of admin-ajax.php with wc-ajax=get_refreshed_fragments, that is cart fragments. Enable the slow query log to catch the specific queries dragging on your busiest pages.

Speed is a revenue lever as well as a technical score: slow stores lose sales, as we cover in how slow websites kill conversions. If you are weighing WooCommerce against a hosted platform while you are here, WooCommerce vs Shopify walks through the trade-offs, and the Core Web Vitals guide for WordPress covers the front-end metrics Google measures once your server side is fast.

Frequently asked questions

Why is my WooCommerce checkout so slow?

Checkout cannot be page-cached, so every request runs full PHP and hits the database, and it occupies a PHP worker for the whole request. Under a traffic spike you can run out of workers and requests queue. A persistent object cache makes each checkout request cheaper, and enough dedicated PHP workers stop the queue building during a sale.

Can you cache WooCommerce cart and checkout pages?

No. Cart, checkout and My Account are unique per visitor and must never be page-cached, or one shopper can be served another's cart. Exclude them by URL and by cookie (bypass the cache for any request carrying woocommerce_items_in_cart or the wp_woocommerce_session cookie), then speed those pages up with a persistent object cache instead.

Does Redis object caching make WooCommerce faster?

Yes, usually significantly on a busy store. WooCommerce repeats the same database lookups within and across requests, and a persistent object cache keeps those results in memory so PHP stops re-querying the database. It is often the biggest win on cart and checkout pages, which cannot be page-cached. It does not fix a bloated database or a slow plugin query, so pair it with cleanup.

How do I clean up a bloated WooCommerce database?

Prune expired transients with wp transient delete --expired, trim autoloaded rows in wp_options, and clear old rows from the WooCommerce sessions and Action Scheduler tables. Limit post revisions and remove orphaned postmeta. Run the safe cleanups monthly with WP-CLI and review the heaviest tables by hand a few times a year.

How many plugins can a WooCommerce site have before it slows down?

There is no fixed limit; what matters is the work each plugin does per request. Ten light plugins can beat three that each run queries and load assets on every page. Use Query Monitor to find plugins adding the most query time on your key templates, and dequeue front-end assets from templates that don't need them.

What causes high TTFB on a WooCommerce store?

High time-to-first-byte on a store usually means the server is doing too much per request: no object cache so the database is queried repeatedly, a bloated database with heavy autoloaded options, a slow plugin query, or not enough PHP workers so requests queue. Measure TTFB on cart and checkout separately from the catalogue, since those pages skip the page cache.

Put this into practice on G7Cloud

Every site runs in its own dedicated container behind ScaleShield, with daily backups that are restore-tested every night. Start on the free plan, no card needed.

About G7Cloud Engineering

Platform team

Articles written by the engineers who build and run G7Cloud: UK managed hosting and the AI Website Builder. We write about what we operate every day: containers, backups, databases, and the small-business websites that run on them.

More about G7Cloud →