WooCommerce stores are harder to speed up than ordinary WordPress sites. Carts, checkout, account pages and logged-in customers can’t be served from a page cache, so every one of those requests runs PHP and hits the database. Speed comes from making those dynamic requests cheap, and caching everything else safely.

1. Page caching, with the right exclusions

Product pages, categories and the home page can be cached for anonymous visitors. These must never be cached:

  • /cart/, /checkout/, /my-account/ (and translated variants);
  • requests with cookies woocommerce_items_in_cart, woocommerce_cart_hash, wp_woocommerce_session_*, wordpress_logged_in_*;
  • ?add-to-cart= and wc-ajax requests.

Good caching plugins know these rules automatically. For Nginx FastCGI cache, add them to the bypass conditions. See Nginx FastCGI cache.

2. Persistent object cache (Redis)

Dynamic store requests repeat many of the same queries (options, product data, sessions). Redis keeps those results in memory, between requests:

sudo apt install -y redis-server php8.3-redis
wp plugin install redis-cache --activate
wp redis enable

On busy stores, this is often the single biggest improvement for cart, checkout and the admin area. See Redis object cache for WordPress.

3. Enable HPOS (High-Performance Order Storage)

HPOS stores orders in dedicated tables, instead of wp_posts and wp_postmeta. It’s faster for order queries, reports and the admin order list, and reduces bloat in the posts tables. New stores use it by default. Older stores can migrate under WooCommerce → Settings → Advanced → Features (sync first, then switch). Check that your plugins declare HPOS compatibility.

4. Cart fragments

The wc-ajax=get_refreshed_fragments request updates the mini-cart on every page. It’s uncached and runs for every visitor. Recent WooCommerce versions load it only where a mini-cart widget is used. If your theme still triggers it everywhere, disable it on pages that don’t need it (many performance plugins have a setting), or use a block-based mini-cart.

5. Action Scheduler and background jobs

WooCommerce queues background tasks (emails, webhooks, subscriptions, analytics) in the Action Scheduler. Problems: thousands of pending or failed actions, and tasks running on visitor requests.

  • Check Tools → Scheduled Actions for large “Pending” or “Failed” counts.
  • Run WP-Cron from a system cron job, not on page loads. See WordPress real cron.
  • Large queues can be processed with WP-CLI: wp action-scheduler run.
  • Clean old completed actions (they’re purged automatically after 30 days by default).

6. Database hygiene

  • Remove expired transients and old sessions: wp transient delete --expired.
  • Limit post revisions, and clean old ones.
  • Keep autoloaded options small.
  • On large catalogues, better indexes help (the Index WP MySQL For Speed plugin).

See WordPress database optimization.

7. Server sizing and PHP-FPM

Uncached requests need PHP workers. If all workers are busy, customers wait in the checkout queue.

8. Front-end weight

9. Search and filtering

The default WooCommerce product search and layered navigation use slow LIKE queries on large catalogues. For thousands of products, consider a dedicated search engine (Elasticsearch/OpenSearch via ElasticPress, or Meilisearch-based plugins). See Meilisearch.

Measure what matters

  • TTFB of uncached pages: add a product to the cart, then time the cart and checkout pages. That’s your real-world dynamic performance.
  • Query Monitor for slow queries and heavy plugins, on a staging copy.
  • Monitor PHP-FPM status (active and idle workers) and server load during sales. See htop.

Quick reference

Area Action
Page cache Cache catalogue; bypass cart, checkout, account and cart cookies
Object cache Redis
Orders Enable HPOS
Background jobs System cron + Action Scheduler cleanup
Server Enough PHP workers, OPcache, InnoDB buffer pool

Related: WordPress VPS performance tuning and WordPress VPS hosting.

  • WooCommerce
  • WordPress
  • Performance