Contents
- Why WooCommerce checkout is different
- Fix 1: Disable cart fragments AJAX
- Fix 2: Clean wp_postmeta table
- Fix 3: Load gateway scripts on checkout only
- Fix 4: Purge expired WooCommerce sessions
- Fix 5: Add object caching (Redis or Memcached)
- Fix 6: Audit checkout plugins with Query Monitor
- Fix 7: Update to WooCommerce 8.x and enable HPOS
- FAQ
A slow WooCommerce checkout in 2026 directly loses you orders. A 1-second delay at checkout drops conversions by up to 7%, and the real causes are almost never your hosting plan. They are WooCommerce-specific: cart fragments firing AJAX requests on every page load, wp_postmeta tables bloated with years of order data, and payment gateway scripts loading across your entire store when they only need to run on one page. This guide walks through 7 root causes and the exact fix for each.
Why WooCommerce Checkout Is Different from a Regular WordPress Page
A WooCommerce checkout page in 2026 runs 80 to 150 database queries per load. A regular WordPress blog post runs 5 to 20. That gap explains why your caching plugin does not help at checkout, because WooCommerce intentionally bypasses page caching on cart and checkout pages. Every visitor has a unique cart, so cached pages are not an option. That means the performance levers are different here: database optimization, server-side object caching, and fixing WooCommerce-specific bottlenecks that do not exist on a regular WordPress site.
If you have already tried image compression, CSS minification, and a faster CDN and your checkout is still slow, those fixes missed the actual problem. The rest of this guide covers what actually moves the needle.
Fix 1: Disable Cart Fragments AJAX
Cart fragments is a WooCommerce feature that fires an AJAX request on every page load across your store, including the homepage, blog posts, and product listings, to update the cart item count in your header. The request goes to /wp-admin/admin-ajax.php and bypasses page caching by design. On a loaded server, it adds 300 to 800 milliseconds to every single pageview, not just checkout.
To confirm this is your issue, open browser DevTools, go to the Network tab, and reload any page on your store. Look for a POST request to admin-ajax.php with the query parameter action=woocommerce_get_refreshed_fragments. If it shows up and takes more than 200ms, cart fragments is your problem.
The fix is one line in your theme’s functions.php:
add_filter( 'woocommerce_cart_fragments_enabled', '__return_false' );
If you use a mini-cart or side-cart plugin that manages its own cart count, you can disable cart fragments completely with no visible change for customers. If you need the live count in your header, the middle-ground fix is moving the request to the footer so it does not block page rendering.
Fix 2: Clean the wp_postmeta Table
WooCommerce stores order metadata, product attributes, and custom field values in your WordPress wp_postmeta table. After 1,000 orders, this table commonly has over 500,000 rows. After 5,000 orders, it can reach millions. Every new checkout query runs against this table, and cleanup never happens automatically. Old revisions, deleted orders, and expired transients all leave orphaned rows behind.
The safest way to clean it is the WP-Sweep plugin (free, by Syed Balkhi). It identifies orphaned postmeta rows, post revisions, and expired transients, shows you exactly how many it found, and lets you remove them with one click before touching anything. After running WP-Sweep, run an OPTIMIZE TABLE wp_postmeta in phpMyAdmin to reclaim space and rebuild the table index. That one operation can take a table that takes 800ms to query down to under 50ms.
We include this cleanup on a quarterly schedule as part of the WooCommerce care plan maintenance we run for client stores.
Fix 3: Load Payment Gateway Scripts on Checkout Pages Only
Stripe, PayPal, and most other payment gateways load their JavaScript libraries on every page of your store by default. Stripe.js alone is around 70 KB. The PayPal SDK adds another 100 KB or more. Both require external network requests to load, and both are render-blocking if placed in the page head. With three or four active payment methods, you have over 300 KB of third-party scripts loading on your homepage, your blog, and every product page.
Start with Stripe’s official WooCommerce plugin. Version 7.0 and newer added a native option under WooCommerce > Settings > Payments > Stripe > Advanced Settings: “Load Stripe.js only on checkout and cart pages.” Enable that before writing any custom code. For other gateways without a built-in option, the fix is wrapping the enqueue in an is_checkout() conditional in functions.php. One gateway fixed this way typically removes 1 to 3 external network requests from every non-checkout page on your store.
Fix 4: Purge Expired WooCommerce Sessions
WooCommerce creates a session record in the wp_woocommerce_sessions database table for every visitor, including search engine bots, scrapers, and spam bots. These sessions expire after 48 hours by default, but the cleanup only runs when a real customer completes a purchase. On a store with meaningful traffic, bots alone can generate thousands of new session rows per day that never get removed.
WooCommerce has a built-in tool for a one-time purge: go to WooCommerce > Status > Tools > Clear expired sessions. On a store that has never run this, you might go from 200,000 session rows to under 500 in a single click. For ongoing maintenance, the WooCommerce Transient Cleaner plugin schedules weekly cleanup automatically. This is another item we handle on a set schedule as part of ongoing WooCommerce maintenance.
Fix 5: Add Object Caching with Redis or Memcached
Without object caching, every database query WooCommerce fires at checkout hits your database server fresh. With Redis or Memcached, repeated results (product data, tax rules, shipping zones, customer meta) are served from memory in under 1 millisecond. WooCommerce’s checkout process reads several of these values multiple times per transaction, so the compounding effect is significant.
Most managed WordPress hosts, including WPX Hosting, Kinsta, and WP Engine, offer Redis as an add-on or default feature. Once it is active on the server, install the Redis Object Cache plugin by Till Kruss (free), connect it to the Redis socket path in wp-config.php with WP_REDIS_SCHEME, and it takes over automatically. Object caching works alongside page caching, not instead of it. It is the highest-impact single change you can make for a high-traffic WooCommerce store where checkout queries are the bottleneck.
Fix 6: Audit Your Checkout Plugins with Query Monitor
Every checkout-specific plugin adds database queries to an already query-heavy page. Order bump plugins, checkout field editors, one-click upsell popups, custom validation scripts, and affiliate tracking pixels all fire during or right before the checkout page load. One plugin with a slow database query can add 500 milliseconds to every single checkout. Two of them can push response time past 3 seconds.
The free Query Monitor plugin by John Blackbourn is the right tool for this audit. Install it, load your checkout page while logged in, and open the database queries panel. It shows you every query fired on that page, which plugin or function triggered each one, and how long each one took. Sort by duration. Any single plugin responsible for more than 20 to 30 queries, or any query taking more than 50ms, is a performance problem worth replacing or removing.
Fix 7: Update to WooCommerce 8.x and Enable HPOS
WooCommerce 8.x introduced High-Performance Order Storage (HPOS), which moves orders out of the legacy wp_posts and wp_postmeta tables into dedicated order tables built specifically for the job. On stores with more than 5,000 orders, enabling HPOS cuts checkout-related database queries by 40 to 60 percent. Stores still on WooCommerce 7.x or lower pay a query-count penalty on every order because the legacy schema was never designed for order volume.
To enable HPOS: go to WooCommerce > Settings > Advanced > Features and switch “Order data storage” to “High-Performance Order Storage.” WooCommerce runs the data migration in the background. Before enabling, update all your WooCommerce extensions and check the official compatibility list, because some older extensions do not support HPOS and will stop working. Running PHP 7.x also eliminates most of the HPOS performance benefit. Both WooCommerce 8.x and PHP 8.1+ together deliver the full query reduction. If you want to update WooCommerce safely without risking a broken checkout, that guide covers the staging-first process we use on every update we manage.
Frequently Asked Questions
Why is WooCommerce checkout slow even though I have a caching plugin?
Because WooCommerce bypasses page caching on cart and checkout pages by design. Caching plugins work by serving pre-built HTML, but every WooCommerce cart is unique per visitor, so the page cannot be cached. The fixes that help checkout are database-level: cleaning tables, adding object caching, and reducing the number of queries per checkout transaction.
How do I confirm cart fragments is causing my slow checkout?
Open your browser’s DevTools, go to the Network tab, and load any page on your store. Filter for XHR or Fetch requests and look for a POST to /wp-admin/admin-ajax.php with action=woocommerce_get_refreshed_fragments. If it appears on every page load and takes more than 200ms, that is your culprit.
Is it safe to disable cart fragments entirely?
Yes, with one tradeoff: the cart item count in your header will no longer update in real time without a page refresh. If you use a side-cart plugin or mini-cart overlay that manages its own count independently, you can disable cart fragments with no visible impact on customers. If the header count matters to you, move it to the footer instead of disabling it so it loads after the page content.
Will cleaning wp_postmeta break my order history?
Not if you use a tool like WP-Sweep that only removes orphaned rows, which are meta entries pointing to posts that no longer exist. It does not touch active order data. Always run a database backup before any cleanup. Never run a generic DELETE against wp_postmeta without specifying orphaned rows only.
What is HPOS and do I need it?
High-Performance Order Storage (HPOS) is a WooCommerce feature introduced in version 7.1 and enabled by default for new installs from version 8.2 onward. It moves order records out of wp_posts and wp_postmeta into dedicated order tables. For stores under a few hundred orders, the difference is small. For stores with thousands of orders, it is the single highest-impact database change available inside WooCommerce itself.
Do I need a developer to apply these fixes?
Fixes 2, 4, 5, and 7 can be done through WooCommerce settings and free plugins with no code required. Fix 1 requires one line in functions.php. Fix 3 may require a small code snippet depending on your payment gateway. Fix 6 just requires installing Query Monitor and reading the output. If you would rather have someone handle all of this on a schedule, our WooCommerce care plans cover it starting at $99 per month.
WooCommerce running slow?
If you would rather have someone run these fixes and keep your store tuned on a schedule, we handle checkout optimization, cleanup, and monitoring as part of our WooCommerce care plans.
