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=andwc-ajaxrequests.
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.
- Measure memory per PHP process (WooCommerce stores often use 80–150 MB per worker). Size
pm.max_childrento fit RAM. See PHP-FPM tuning. - Use a recent PHP 8.x with OPcache. See php.ini settings.
- Give MySQL a sensible
innodb_buffer_pool_size. See MySQL performance tuning. - Requirements by store size: WooCommerce VPS requirements.
8. Front-end weight
- Optimize product images (WebP/AVIF, correct sizes). See WordPress image optimization.
- Remove unused plugins and scripts. Each plugin can add CSS and JS to every page.
- Serve static assets from a CDN. See WordPress CDN setup.
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.