Here’s a frustratingly common story. A WooCommerce store owner installs a caching plugin, gets great scores on the homepage, and the checkout still takes 8 seconds. They try a better caching plugin. Same result. They blame the host. Same result.
The problem was never caching. WooCommerce’s cart, checkout and account pages are uncacheable by design. They show personalized data, so every visit runs the full WordPress stack: PHP, dozens of database queries, payment gateway calls. Caching plugins deliberately exclude these pages, and they should.
So if caching can’t help, what actually makes checkout fast? This guide covers the five real culprits (cart fragments, autoload bloat, slow gateway calls, old order storage, and the missing object cache) and how to fix each one.
The short version: checkout speed is database + PHP speed. Cut cart fragment AJAX calls, shrink autoloaded options, enable HPOS, add Redis object caching, and audit your payment gateway. Measure with uncached tests only — cached scores are meaningless here.
Why Caching Can’t Fix Checkout (And Shouldn’t)
Page caching works by serving the same HTML to everyone. But checkout pages are different for every customer: their cart contents, their address, their payment methods. Serving a cached checkout to the wrong person would be a data-leak disaster.
So every caching plugin (WP Rocket, FlyingPress, LiteSpeed Cache, all of them) automatically excludes cart, checkout and account pages from the page cache. This is correct behavior. It also means:
- Your PageSpeed score on the homepage says nothing about checkout speed. Test checkout separately, always uncached.
- “Full page cache” solutions that claim to cache checkout are lying or dangerous. Don’t.
- Checkout optimization is backend optimization: faster database queries, faster PHP, fewer external calls. The unsexy stuff.
With that understood, here are the five culprits in order of how often they cause the problem.
Culprit 1: Cart Fragments (The AJAX Tax on Every Page)
WooCommerce’s cart fragments are small AJAX requests (admin-ajax.php?action=get_refreshed_fragments) that update the cart widget without reloading the page. Sounds harmless, except:
- They fire on every page load, not just cart pages — including your homepage, blog posts, landing pages.
- Each one is an uncacheable, full WordPress bootstrap request: PHP + database, just to check if the cart changed.
- On sites with many visitors, fragments can account for a shocking share of total server load.
The fix: if your theme doesn’t show a live cart widget in the header (or you can live without instant cart updates), disable cart fragments entirely. Many performance plugins (Perfmatters, for example) offer a one-click toggle, or a small code snippet does it. If you need the widget, at least make sure it’s the only thing triggering the request. Some themes and plugins fire fragment refreshes redundantly.
This single change often improves whole-site speed, not just checkout, because it removes an uncacheable PHP request from every page view.
Culprit 2: Autoload Bloat (Death by a Thousand Options)
WordPress loads every option marked autoload=yes in the wp_options table on every single request: frontend, checkout, admin, everything. WooCommerce and its extensions are prolific autoloaders: settings, transients, session data, marketing opt-ins, wizard states.
On a store that’s been running for years, autoloaded data can balloon into megabytes. That means megabytes of database reading before WordPress even starts building your checkout page. It’s pure overhead — the same tax on every request.
The fix:
1. Measure first. Query Monitor shows autoload size, or run a quick database query to list the largest autoloaded options. You’ll usually find a few plugin options hogging most of the space.
2. Fix at the source. The worst offenders are often transients that should never have been autoloaded, or plugins storing logs/caches in options. Update the plugin, change its settings, or replace it.
3. Clean carefully. Don’t blindly delete options. Some are load-bearing. Disable autoload on heavy non-critical options rather than deleting them, and always back up first.
Stores that fix autoload bloat often see checkout times drop by seconds, because the checkout does more database work per request than any other page.
Culprit 3: Slow Payment Gateway and External Calls
During checkout, your server talks to the outside world: payment gateway APIs, fraud checks, tax calculators, shipping rate APIs, email services. Each external call adds its full response time to your page load, and you can’t control how fast Stripe, PayPal or a tax API responds.
Diagnose with Query Monitor’s HTTP API Calls panel during a test checkout: look for external requests and their durations. Common findings:
- A gateway’s API taking 1–2 seconds per call, sometimes called twice (authorize + capture, or redundant status checks).
- Fraud-prevention plugins adding their own API round trips.
- Tax/shipping plugins querying external services synchronously instead of caching rates.
Fixes:
– Cache what you can: tax tables and shipping rates don’t change every minute. Cache them in transients.
– Audit gateway plugins: some payment plugins are dramatically heavier than others. If your gateway adds seconds, investigate alternatives or ask the gateway’s support about their API latency.
– Defer non-critical calls: order confirmation emails, CRM syncs and analytics events don’t need to block the checkout response. Move them to background processing (WooCommerce’s Action Scheduler exists for exactly this).
Never “fix” this by increasing timeouts. That just lets slow calls take longer.
Culprit 4: Old Order Storage (Enable HPOS)
WooCommerce historically stored orders as WordPress posts (wp_posts + wp_postmeta). A flexible but slow design for high-volume stores, because order queries join against huge meta tables. HPOS (High-Performance Order Storage) stores orders in dedicated tables built for the job, with proper indexes.
If your store was created before HPOS became the default, you might still be on the old storage, leaving significant checkout and admin speed on the table.
The fix: WooCommerce → Settings → Advanced → Features → enable High-performance order storage, then run the migration. Notes:
- Back up first. This migrates your order data.
- Check plugin compatibility: the screen shows which of your extensions declare HPOS compatibility. Incompatible plugins can break order handling; update or replace them before migrating.
- After migration, keep the old data for a while (WooCommerce offers a compatibility mode), then remove it once you’re confident.
For stores with thousands of orders, HPOS is one of the highest-impact single changes available.
Culprit 5: No Object Cache (Redis for Dynamic Pages)
Here’s the cruel irony: the pages that need speed most (checkout, cart, account) are the pages page caching can’t touch. But object caching works on every page, cached or not.
Redis object caching stores database query results in RAM. Checkout runs dozens of queries — product data, customer data, session data, tax rules, shipping zones. With Redis, repeat queries return from memory in microseconds. Without it, every checkout hammers MySQL on disk.
For a content site, Redis is a nice optimization. For a WooCommerce store, it’s close to mandatory: it’s the only caching layer that accelerates your uncacheable pages. Many managed WooCommerce hosts include Redis as a toggle — if yours does, turn it on before doing anything else on this list.
How to Measure Checkout Speed Honestly
Forget homepage scores. Here’s the honest test protocol:
- Use an incognito window (logged-out behaves differently from admin).
- Add a product to the cart and go to checkout — time the page load with DevTools (F12 → Network, look at the document request time).
- Test the AJAX, not just the page: the checkout “Update” and “Place order” actions are AJAX requests. Time those in the Network tab — a checkout page that loads in 2s but takes 6s to place the order is still broken.
- Compare before/after each fix on this list. Change one thing, measure, keep what works.
- Test under load eventually: one fast checkout means little if ten simultaneous checkouts melt the server. That’s hosting capacity planning — a separate (but related) conversation.
Also verify your static assets are served efficiently (test whether your CDN is actually working), because checkout pages still load CSS, JS and images, and a misconfigured CDN slows every page equally.
For the broader optimization picture, our 20-step WordPress performance checklist covers the full stack.
Frequently Asked Questions
Why is my WooCommerce checkout slow but my homepage is fast?
Because your homepage is page-cached and your checkout can’t be. The homepage score measures your cache; the checkout measures your actual server, database and PHP speed. They’re different systems — optimize them separately.
Will a better caching plugin speed up my checkout?
No. All reputable caching plugins exclude cart/checkout/account pages from page caching, as they must. If a plugin claims to cache checkout pages, avoid it — that’s a correctness bug, not a feature. Speed up checkout with object caching (Redis), database cleanup and gateway audits instead.
What are cart fragments and should I disable them?
Cart fragments are AJAX requests that refresh the cart widget without a page reload. They run a full uncacheable WordPress request on every page view. If your theme doesn’t display a live cart widget — or you can accept the cart updating on page load instead of instantly — disabling them removes significant server load site-wide.
Is HPOS safe to enable on an existing store?
Generally yes, with precautions: back up, check the HPOS compatibility list for your plugins (WooCommerce shows this on the feature screen), run the migration, and keep compatibility mode on until you’ve verified orders process correctly. Most modern extensions support it; older or abandoned ones may not.
How much does Redis help WooCommerce specifically?
More than on a content site, because it’s the only cache layer that touches your uncacheable pages. Every checkout, cart and account request benefits from queries served from RAM instead of MySQL. It’s routinely the difference between a checkout that feels sluggish and one that feels instant — which is why many managed WooCommerce hosts enable it by default.
The Bottom Line
WooCommerce checkout speed was never a caching problem — it’s a database and PHP problem wearing a caching costume. The fixes, in order of usual impact: disable cart fragments you don’t need, fix autoload bloat, audit gateway and external calls, enable HPOS, and add Redis object caching. The one cache layer that actually touches checkout.
Measure checkout like a customer, not like PageSpeed Insights: incognito window, real cart, timed AJAX. Fix what the evidence points to. Your conversion rate will thank you. Slow checkouts don’t just annoy visitors, they abandon carts.

