← All articles

September 4, 2026 · Vedanshu Jain

Why WooCommerce Checkout Is Slow: Root Causes, Diagnosis, and Fixes Ranked by Impact

Why WooCommerce checkout is slow: six root causes from uncached requests to stock locks, how to trace each one, and fixes ranked by impact.

Why WooCommerce checkout is slow comes down to one fact: nothing on the checkout can be served from cache, so every keystroke, address change, and payment attempt runs PHP, hits MySQL, and often calls a third-party API. Six root causes explain almost every slow checkout, each has a specific trace signature, and the fixes rank clearly by impact.

Why the checkout cannot be cached

WooCommerce’s caching guidance requires that Cart, Checkout, and My Account stay dynamic and that any request carrying the woocommerce_cart_hash, woocommerce_items_in_cart, or wp_woocommerce_session_* cookies bypass the page cache (source). That is correct — the page is personal — but it means a slow checkout is showing you the true cost of an uncached WooCommerce request: bootstrapping WordPress and every active plugin, loading the session, rebuilding the cart, recalculating totals, and rendering the form. On the classic checkout this happens on the initial page load and again on every ?wc-ajax=update_order_review call; on the block checkout it happens through the Store API’s /wc/store/v1/cart and /checkout endpoints (source). WooCommerce 11.1 made Store API and REST requests 30–42% faster by skipping block registration on non-rendering requests (source), which is a reason to update, but it lowers the floor rather than removing it.

The six root causes

1. Uncached dynamic requests doing too much per call

A stock WooCommerce checkout recalculates the whole cart on each update: stock status per line, shipping packages, taxes, coupons, fees, and gateway availability. One engineer’s measurement put update_order_review at 700–1,100 ms on a clean install with a stock theme and no extra plugins (source); that is the baseline before your plugins add anything. Every plugin that hooks woocommerce_cart_calculate_fees, woocommerce_checkout_fields, or woocommerce_available_payment_gateways adds its own work to that path.

2. Shipping and tax API calls on every update

Live-rate carriers and tax services are called when the shipping package changes. WooCommerce stores calculated rates in the session keyed on a hash of the package, so the same cart to the same address should not re-fetch (source), but a shopper typing a postcode changes the package hash on each keystroke, and a plugin that adds a timestamp or session ID to the package defeats the cache entirely. Each round trip is typically 300–1,500 ms of pure wait time during which the totals area spins.

3. Cart fragments and AJAX storms

The classic cart-fragments script fires ?wc-ajax=get_refreshed_fragments on page load and after cart changes. Since WooCommerce 7.8 it only loads when the Cart Widget is rendered, and the Mini-Cart block does not use it at all (source). Themes that hardcode the widget, plus plugins that trigger update_checkout on every field event, produce several overlapping uncached requests per user action. On a sale day that multiplies origin load by the number of fields on the form.

4. Payment gateway round trips

Modern gateways create a payment intent or token server-side before the form submits, confirm it on submit, and sometimes fetch saved methods or a client secret on page load. Three to four sequential calls to a payment provider at 200–600 ms each is a second or more before WooCommerce even creates the order.

5. Database locks on stock

Since WooCommerce 4.3 the checkout reserves stock through the wp_wc_reserved_stock table using an atomic INSERT … SELECT … FOR UPDATE, holding the reservation for the configured woocommerce_hold_stock_minutes (source). That is what prevents overselling, and it works by making concurrent checkouts for the same product wait on a row lock. For a limited drop where hundreds of shoppers hit “Place order” on one SKU within seconds, lock waits stack up, PHP workers sit idle holding connections, and the whole checkout queue slows.

6. Heavy hooks and plugins on the checkout path

Anything hooked to init, woocommerce_init, template_redirect, or woocommerce_checkout_update_order_review runs on every checkout request. The usual offenders are analytics or CRM plugins that call home synchronously, abandoned-cart trackers writing to the database on each field change, marketing plugins recomputing recommendations, and license checks that make an HTTP request when their transient expires. None of these are visible in the checkout HTML; they show up only in a trace.

How to diagnose each one

You need two instruments. An APM that traces each request into SQL statements, outbound HTTP calls, and the PHP functions between them tells you where the milliseconds go on production, across thousands of checkouts, at the 95th percentile. Query Monitor gives you the same picture for a single request on staging, including AJAX and REST calls, with time attributed per plugin, per hook, and per HTTP API call.

Work through the causes in order. Open the update_order_review or Store API trace and read the waterfall. A long span with no children is PHP time in a hook — sort Query Monitor’s Hooks panel by time to find the callback. Many short queries against wp_postmeta or wp_options is an N+1 pattern or missing object cache. A single span to an external host is a shipping, tax, or gateway call; Query Monitor’s HTTP API Calls panel lists the URL, duration, and calling plugin. A query on wc_reserved_stock or wp_postmeta with a long execution time but a trivial plan is a lock wait — confirm with SHOW ENGINE INNODB STATUS during the spike. And a browser network tab showing several wc-ajax requests in flight at once is an AJAX storm, regardless of how fast each one is individually.

Symptom, cause, check, fix

Symptom Likely cause Check Fix
Totals spinner after every keystroke in the address Shipping or tax API call per package change; AJAX on every field event Query Monitor HTTP API Calls on update_order_review; browser network tab Trigger recalculation on blur or postcode completion only; make the package hash stable; cache carrier rates
Checkout is 1–2 s slower than the cart page Gateway pre-flight calls on page load (intent, saved methods, client secret) APM trace: sequential spans to the payment host Defer intent creation to submit; enable express checkout; use a gateway with a single confirm call
Slow only when the site is busy PHP worker exhaustion from uncached requests, or missing object cache PHP-FPM queue length; ratio of queries to cached hits per request Persistent Redis object cache; more workers or auto-scaling; fix cookie-bypass caching so catalog pages stay cached
“Place order” hangs during a drop, then fails for some shoppers Row locks on wc_reserved_stock for one hot SKU SHOW ENGINE INNODB STATUS lock waits; slow query log on INSERT … SELECT Lower woocommerce_hold_stock_minutes; shorten MySQL lock wait timeout; separate the drop SKU from general checkout traffic
Every checkout request has a fixed 200–500 ms of unexplained PHP time Heavy hooks: license checks, analytics, CRM sync on init Query Monitor Hooks panel sorted by time; HTTP API Calls Move to async or Action Scheduler; remove the plugin from checkout with a conditional load
Dozens of wc-ajax requests per page view Hardcoded cart widget plus plugins calling update_checkout Browser network tab filtered to wc-ajax Switch to the Mini-Cart block; remove duplicate triggers; debounce custom scripts
Hundreds of small queries per request Missing persistent object cache; unindexed meta queries Query Monitor Queries by Caller; slow query log at 100 ms Redis object cache; add indexes or rewrite the query; migrate orders to HPOS
Order placed but the redirect takes 3 s or more Synchronous work on woocommerce_checkout_order_processed (emails, webhooks, ERP push) APM trace after the order INSERT Queue emails and integrations through Action Scheduler on a system cron

Fixes ranked by impact

  1. Get every uncached request off the checkout that does not belong there. Remove AJAX storms, hardcoded fragments, and synchronous plugin hooks. This typically halves the request count and is free.
  2. Add a persistent object cache and fix the database. Redis for options and product data, indexes for meta queries, and High-Performance Order Storage so order creation and lookup use dedicated tables — WooCommerce’s benchmark showed order creation about 5× faster under HPOS (source).
  3. Make external calls rare and parallel. Stable package hashes so shipping rates hit WooCommerce’s per-session rate cache; tax lookups only on address completion; gateway intent creation deferred to submit.
  4. Move post-order work off the request. Emails, webhooks, and ERP syncs go to Action Scheduler backed by a system cron, not WP-Cron; Action Scheduler’s own FAQ treats a day-old backlog as a fault (source).
  5. Size and scale PHP for uncached traffic. Enough workers for the concurrent checkouts you expect at peak, auto-scaling for the spike, PHP 8.3 or newer with OPcache sized to your codebase; WooCommerce 10.8 and later require 8.3 (source).
  6. Handle hot-SKU locking deliberately. Short stock holds, tight lock timeouts, and a load test that places concurrent orders for one product before the drop.

How Urumi handles this

Urumi is the platform layer for WooCommerce stores doing $1M–$50M in GMV, where a slow or failing checkout is a measurable revenue leak rather than an annoyance. The fully managed APM captures every checkout request as a trace with SQL, outbound calls, and hook timing, so the diagnosis section above is a dashboard rather than a project. Revenue AI watches checkout, cart, pricing, and payments around the clock; prices every regression in dollars and ships the fix as a PR. Under stress tests with the edge cache disabled, the platform held a 236 ms median cart response and a 321 ms median checkout while processing 7,861 orders in under two minutes, which is the uncached path this article is about. Already have a team or an agency? They ship faster with the grunt work covered. Details at managed WooCommerce hosting on Urumi.

Frequently asked questions

Why is WooCommerce checkout slower than the rest of the site?

Because checkout pages and their AJAX or Store API requests must bypass full-page caching — they are personal to each shopper — so every interaction runs PHP, queries the database, and often calls shipping, tax, or payment APIs. The rest of the site is mostly served from cache.

Does disabling cart fragments speed up checkout?

It removes one uncached request per page view, which helps origin load more than it helps a single checkout. Since WooCommerce 7.8 the script only loads when the classic Cart Widget is rendered; switching to the Mini-Cart block achieves the same result without breaking the cart count.

Will HPOS make my checkout faster?

Modestly on its own — WooCommerce’s benchmark measured checkout about 1.5× faster and order creation about 5× faster on a 400,000-order store. It is one fix among several, not the whole answer.

How do I find which plugin is slowing down checkout?

Install Query Monitor on staging, load the checkout, trigger an address change, and open the Queries by Component, Hooks, and HTTP API Calls panels; each attributes time to a plugin. On production, an APM trace of update_order_review or the Store API checkout call shows the same breakdown at scale.

For the infrastructure side of the same problem, read why WooCommerce slows down under load and how many PHP workers WooCommerce needs.

Last reviewed September 2026. Competitor details come from their public pages on the dates linked; check them before you buy.

Built by the people who built WooCommerce core.

We built WooCommerce core at Automattic — the parts that matter in production: performance, payments, reliability. Earlier, engineering at HackerRank (Y Combinator) through its enterprise scale-up. Naman led Payments and WooCommerce releases to 4.5M merchants; Vedanshu led HPOS, Taxes, and Shipping. Run by AI, overseen by the people who built WooCommerce core.

Grow your store's revenue on Urumi.

The AI platform D2C brands use to grow revenue — built by the people who built WooCommerce core.

See the WooCommerce platform  ·  Start your WooCommerce store on Urumi  ·  Talk to the founders

Agent live · 99.99% uptime · shipping today.