---
title: "WooCommerce speed optimization: an engineer’s order of work"
id: "550"
type: "post"
slug: "woocommerce-speed-optimization"
published_at: "2026-10-06T20:00:48+00:00"
modified_at: "2026-10-06T20:00:48+00:00"
url: "https://danielpazwp.com/woocommerce-speed-optimization/"
markdown_url: "https://danielpazwp.com/woocommerce-speed-optimization.md"
excerpt: "WooCommerce speed optimization in order: cache exclusions for cart and checkout, cart fragments, object cache, HPOS, database and product pages."
taxonomy_category:
  - "Performance"
---

[Performance](https://danielpazwp.com/category/performance/)
8 min read

# WooCommerce speed optimization: an engineer’s order of work

WooCommerce speed optimization in order: cache exclusions for cart and checkout, cart fragments, object cache, HPOS, database and product pages.

Published **06/10/2026**8 min read

[Written byDaniel PazDaniel Paz has worked on the web for more than 14 years and has focused on WordPress since 2016. He is CEO and founder of WebOption, creator of WP Alta Performance (Brazil’s reference channel on WordPress optimization) and has shipped WordPress for Globo, Shell, Endeavor, Estratégia Concursos and Brazil’s Federal Government. He speaks at WordCamp Brazil, WordCamp Canada and WordCamp US, TDC and PHP Conference Brazil.](https://danielpazwp.com/author/daniel-paz/)

WooCommerce speed optimization starts with the fact that a store has two kinds of pages. Catalog pages (home, categories, products) can be served from a page cache like any WordPress page. Cart, checkout and account pages can’t, because they are different for every customer. So you cache the catalog hard, exclude cart, checkout and my account from that cache, and make the uncached part fast with a persistent object cache, a tuned database, High-Performance Order Storage (HPOS) and as few cart fragment requests as possible. Then you deal with images, scripts and third-party tags on product pages.

Most slow stores I audit are slow for structural reasons, not because of one bad plugin. This guide is the order I work through a WooCommerce store. It is part of my guide on [how to speed up WordPress](https://danielpazwp.com/speed-up-wordpress/)
; if your problem is a failing Core Web Vitals report in Search Console, also read [WooCommerce Core Web Vitals](https://danielpazwp.com/woocommerce-core-web-vitals/)
, which goes metric by metric.

## Why is WooCommerce slower than a normal WordPress site?

A blog serves the same HTML to almost everyone. A store has sessions, carts, prices that change with tax rules and currency, stock levels and logged-in customers. Every one of those makes a request harder to cache. When a request misses the cache, WordPress loads WooCommerce, queries products and their meta, checks the session and builds the page in PHP. On a store with many products, variations and extensions, that path is long.

The second reason is plugins. Stores tend to collect extensions for shipping, payments, reviews, wishlists, filters, upsells and marketing tags, and each one can add database queries, scripts and external requests.

## What should the page cache include and exclude?

Get this right first, because it decides how many requests ever reach PHP.

| Page or request | Cache it? | Why |
| --- | --- | --- |
| Home, category and product pages for visitors with an empty cart | Yes | Same HTML for everyone |
| Cart, checkout and my account | No | Personal content and payment flow |
| Any request with the cart or session cookies set (woocommerce_items_in_cart, woocommerce_cart_hash, wp_woocommerce_session_*) | Usually no, or serve a cached page without personal parts | The visitor has a cart |
| Requests with add-to-cart in the query string | No | They change state |
| ?wc-ajax= endpoints | No | They are dynamic by design |
| Logged-in customers | Depends on the cache layer | Many setups bypass the cache for them |

Most WooCommerce-aware caching plugins and managed hosts set these exclusions for you. Check them anyway, especially after moving the cart or checkout to a different URL or adding a second language, because the exclusion is often tied to the page, not to its purpose. If a campaign adds UTM parameters to every link, make sure the cache ignores those parameters instead of creating a new cache entry or bypassing it. For how page, object and edge caches fit together, read [page cache, object cache and edge cache](https://danielpazwp.com/page-cache-object-cache-edge-cache-which-one-you-actually-need/)
 (my explainer on which one you need).

## What are cart fragments, and should you disable them?

Cart fragments are the classic WooCommerce mechanism to keep the mini cart in the header up to date on cached pages. The `wc-cart-fragments` script sends an AJAX request to `?wc-ajax=get_refreshed_fragments` after the page loads, and that request is never cached, so it runs WordPress and WooCommerce on every page view.

Recent WooCommerce versions no longer load that script on every page by default; they load it where the legacy cart widget needs it. In practice I still find it everywhere, because themes and plugins enqueue it themselves. My approach:

- Check the network panel for `get_refreshed_fragments` requests on pages where no cart is shown.
- If the theme’s header cart needs it, keep it but stop it on pages where the header doesn’t show a count, or switch to the mini cart block, which works differently.
- If nobody needs it, dequeue it. Then test add to cart on a cached page and confirm the cart count still updates where it is visible.

This is one of the changes I measure before and after on the server side too, because removing an uncached request on every page view lowers PHP load during traffic peaks.

## Does WooCommerce need a persistent object cache?

For a store with real traffic, yes. Without a persistent object cache, WordPress caches query results only for the length of one request. With Redis or Memcached, options, product data, term lookups and transients stay in memory between requests, which shortens every uncached request: cart, checkout, account pages and admin. Two caveats from audits: the object cache only helps if the host gives it enough memory, and WooCommerce customer sessions live in their own database table, so the object cache doesn’t replace a healthy database. Setup and checks are in my guide to [Redis object cache for WordPress](https://danielpazwp.com/wordpress-redis-object-cache/)
.

## Should you switch to High-Performance Order Storage?

HPOS stores orders in dedicated tables instead of spreading them across `wp_posts` and `wp_postmeta`. That makes order queries simpler and keeps the posts and postmeta tables smaller, which helps both checkout writes and the admin order screens. New stores use it by default in recent versions; older stores have to migrate.

The setting is under WooCommerce > Settings > Advanced > Features. My migration routine:

- Confirm every active extension declares HPOS compatibility. WooCommerce shows a warning when one doesn’t.
- Turn on compatibility mode so orders sync to both storages, and let the sync finish.
- Switch the authoritative storage to HPOS on staging, test checkout, refunds, order emails and any integration that reads orders (ERP, invoicing, shipping).
- Do the same in production, watch for a while, and then turn off compatibility mode. Keeping sync on permanently means every order write happens twice.

## What else slows down the uncached part?

After the cache and HPOS, the uncached requests are where stores lose time. The usual causes:

- Large autoloaded options in `wp_options`, loaded on every request. WordPress 6.6 added a Site Health check for autoload size. My guide to [WordPress database optimization](https://danielpazwp.com/wordpress-database-optimization/) shows how to find the heavy rows.
- Expired transients and a `wp_actionscheduler_actions` table with years of completed actions.
- Product filters that run unindexed meta queries on large catalogs.
- Extensions calling external APIs (shipping rates, tax services, license checks) during the request.
- PHP workers that are too few for the checkout traffic, so requests queue at the server.

Query Monitor, on staging or for an admin user, shows slow queries and external HTTP calls per request. That is where I start when checkout TTFB is high.

## How do you speed up product and category pages?

These are the pages Google measures most, and most of what applies to any WordPress page applies here. The parts that are specific to stores:

- Product galleries. The main product image is usually the LCP element. Don’t lazy load it, serve it at the size it displays and in WebP or AVIF, and check that the gallery script doesn’t swap it after load.
- Variation swatches and gallery zoom add JavaScript that runs on interaction. Test INP on a product with many variations, not on a simple product.
- Category pages with filters. Filter plugins often load their full script and CSS on every page. Scope them to the shop and category pages.
- Third-party tags. Pixels for ads, reviews widgets and chat often add more JavaScript than WooCommerce itself. Audit them with the marketing team and remove the ones nobody reads reports from.

The metric-level detail is in [WooCommerce Core Web Vitals](https://danielpazwp.com/woocommerce-core-web-vitals/)
 and in [fixing INP in WordPress](https://danielpazwp.com/inp-wordpress/)
.

## What should you measure during WooCommerce speed optimization?

Measure the catalog and the checkout separately, because they fail for different reasons:

- field LCP, INP and CLS for product and category templates in Search Console or CrUX
- TTFB on a cached product page and on an uncached cart or checkout request
- the number of uncached `wc-ajax` requests per page view
- slow queries and external HTTP calls on checkout, from Query Monitor
- order list load time in the admin, before and after HPOS

If the admin is the part that hurts, I wrote a separate guide on how to [fix a slow WooCommerce admin](https://danielpazwp.com/woocommerce-slow-admin/)
.

## Frequently asked questions

### Can you cache the WooCommerce checkout?

No. Checkout must be generated per customer. Make the uncached request fast instead, with an object cache, a lean database, enough PHP workers and few external calls.

### Do I need a WooCommerce-specific host?

You need a host that understands the cache exclusions above, gives you Redis or Memcached and enough PHP workers for peaks. Some hosts market that as WooCommerce hosting; check the features rather than the label.

### Is disabling cart fragments safe?

It is safe when no visible element depends on them. Test the add to cart flow and the header cart on a cached page after removing them.

If your store is losing time in checkout or failing Core Web Vitals on product pages and you want someone to find the cause, I work on exactly this as a [WooCommerce consultant](https://danielpazwp.com/woocommerce-consultant/)
: I diagnose the store, prioritize the fixes and check them against field data. When the plan needs hands, the [WebOption team handles the implementation](https://weboption.com.br/performance-seguranca/)
.

[Work with Daniel](https://danielpazwp.com/#book)
[More in Performance](https://danielpazwp.com/category/performance/)

[About the authorDaniel Paz has worked on the web for more than 14 years and has focused on WordPress since 2016. He is CEO and founder of WebOption, creator of WP Alta Performance (Brazil’s reference channel on WordPress optimization) and has shipped WordPress for Globo, Shell, Endeavor, Estratégia Concursos and Brazil’s Federal Government. He speaks at WordCamp Brazil, WordCamp Canada and WordCamp US, TDC and PHP Conference Brazil.Author page](https://danielpazwp.com/author/daniel-paz/)

## Related articles

[All articles](https://danielpazwp.com/blog/)

[Performance Oct 2026Elementor vs Gutenberg performance: what the architecture means](https://danielpazwp.com/elementor-vs-gutenberg-performance/)
[Performance Oct 2026How to fix a slow WooCommerce admin](https://danielpazwp.com/woocommerce-slow-admin/)
[Performance Oct 2026Best WordPress caching plugin: how to choose for your server](https://danielpazwp.com/best-wordpress-caching-plugin/)
