WooCommerce Performance Optimization
Before writing code
Fetch live docs:
- Web-search
site:developer.woocommerce.com performance for performance guide
- Web-search
woocommerce hpos performance benefits for HPOS optimization details
- Web-search
wordpress object caching best practices for caching patterns
HPOS (High-Performance Order Storage)
Why It Matters
HPOS moves orders from wp_posts/wp_postmeta to dedicated tables:
- Dramatically faster order queries (custom indexes)
- Reduces
wp_posts table bloat
- Better database performance at scale
- Required for WooCommerce's future direction
Enabling HPOS
WooCommerce > Settings > Advanced > Features:
- Enable "Custom order tables"
- Run the migration tool to migrate existing orders
- Enable "Sync" during transition period
- Once verified, disable sync and use custom tables as authoritative
Compatibility Requirements
Extensions must:
- Use CRUD methods (
$order->get_meta(), $order->set_status(), $order->save())
- NOT use
get_post_meta() / update_post_meta() on orders
- NOT use
WP_Query with post_type => 'shop_order'
- Declare compatibility via
FeaturesUtil::declare_compatibility()
Object Caching
WordPress Object Cache
wp_cache_get() / wp_cache_set() — in-memory cache per request:
- With Redis/Memcached: persistent across requests
- Always use cache groups:
wp_cache_set( $key, $data, 'my_plugin' )
- Set appropriate expiration
- Use
wp_cache_delete() when data changes
Transients
set_transient() / get_transient() — cached values with expiration:
- Stored in DB without object cache, in-memory with object cache
- Use for: API responses, computed values, rate calculations
- Always handle cache miss (regenerate data when transient expires)
- Delete transients when underlying data changes
WooCommerce Cache Helpers
WC_Cache_Helper — manages WooCommerce-specific caching
wc_get_transient_version( 'product' ) — cache versioning for products
- Cache invalidation on product/order changes via version bumps
Database Optimization
Query Optimization
- Use
wc_get_orders() / wc_get_products() instead of WP_Query
- Limit queries: always use
limit/per_page parameters
- Avoid
meta_query on large tables — use HPOS custom columns instead
- Use
'fields' => 'ids' when you only need IDs
- Avoid
'no_found_rows' => false on large result sets
Index Optimization
- Ensure custom tables have proper indexes on queried columns
- WooCommerce HPOS tables include optimized indexes by default
- For custom tables: add indexes on columns used in WHERE, JOIN, ORDER BY
Background Processing
Move heavy operations out of the request cycle:
- Action Scheduler — WooCommerce's job queue
- Schedule:
as_schedule_single_action( $timestamp, 'hook_name', $args )
- Recurring:
as_schedule_recurring_action( $timestamp, $interval, 'hook_name', $args )
- Handles retries, failure logging, and concurrent execution
Frontend Performance
Asset Loading
- Conditionally load CSS/JS only on relevant pages
- Use
wp_enqueue_script with strategy => 'defer' or 'async'
- Combine/minify assets in production
- Use
wp_script_add_data( $handle, 'strategy', 'defer' )
Cart Fragments
AJAX cart fragment refreshing can be a bottleneck:
- Filter
woocommerce_cart_fragments to minimize data
- Disable on pages where cart widget isn't shown
- Use
wc_cart_fragments_params localized data
Image Optimization
- Use WordPress responsive images (
srcset, sizes)
- Enable lazy loading:
loading="lazy" on product images
- Use WebP format where supported
- Configure image sizes:
add_image_size() and WooCommerce image settings
Action Scheduler
Using Action Scheduler
WooCommerce's built-in background job processor:
as_schedule_single_action( time(), 'my_hook', $args, 'my-group' ) — run once
as_schedule_recurring_action( time(), HOUR_IN_SECONDS, 'my_hook', $args ) — recurring
as_enqueue_async_action( 'my_hook', $args ) — ASAP execution
as_unschedule_action( 'my_hook', $args ) — cancel
- Monitor via WooCommerce > Status > Scheduled Actions
When to Use
- Sending batch emails
- Syncing inventory with external systems
- Generating reports
- Processing large data imports/exports
- Cleaning up expired data
Best Practices
- Enable HPOS for new stores and migrate existing ones
- Use persistent object cache (Redis/Memcached) in production
- Cache expensive computations and API responses with transients
- Use Action Scheduler for background processing — never process heavy tasks during HTTP requests
- Profile with Query Monitor plugin to identify slow queries
- Conditionally load assets only on pages where needed
- Use
wc_get_orders() / wc_get_products() with appropriate limits
- Avoid N+1 query patterns — batch load related data
Fetch the WooCommerce performance documentation and HPOS migration guide for exact configuration, migration steps, and optimization techniques before implementing.
1---2name: woo-performance3description: Optimize WooCommerce performance — object caching, transients, HPOS, database optimization, Action Scheduler, lazy loading, and query optimization. Use when improving store performance or diagnosing slowness.4---5
6# WooCommerce Performance Optimization
7
8## Before writing code
9
10**Fetch live docs**:
111. Web-search `site:developer.woocommerce.com performance` for performance guide
122. Web-search `woocommerce hpos performance benefits` for HPOS optimization details
133. Web-search `wordpress object caching best practices` for caching patterns
14
15## HPOS (High-Performance Order Storage)
16
17### Why It Matters
18
19HPOS moves orders from `wp_posts`/`wp_postmeta` to dedicated tables:
20- Dramatically faster order queries (custom indexes)
21- Reduces `wp_posts` table bloat
22- Better database performance at scale
23- Required for WooCommerce's future direction
24
25### Enabling HPOS
26
27WooCommerce > Settings > Advanced > Features:
28- Enable "Custom order tables"
29- Run the migration tool to migrate existing orders
30- Enable "Sync" during transition period
31- Once verified, disable sync and use custom tables as authoritative
32
33### Compatibility Requirements
34
35Extensions must:
36- Use CRUD methods (`$order->get_meta()`, `$order->set_status()`, `$order->save()`)
37- NOT use `get_post_meta()` / `update_post_meta()` on orders
38- NOT use `WP_Query` with `post_type => 'shop_order'`
39- Declare compatibility via `FeaturesUtil::declare_compatibility()`
40
41## Object Caching
42
43### WordPress Object Cache
44
45`wp_cache_get()` / `wp_cache_set()` — in-memory cache per request:
46- With Redis/Memcached: persistent across requests
47- Always use cache groups: `wp_cache_set( $key, $data, 'my_plugin' )`
48- Set appropriate expiration
49- Use `wp_cache_delete()` when data changes
50
51### Transients
52
53`set_transient()` / `get_transient()` — cached values with expiration:
54- Stored in DB without object cache, in-memory with object cache
55- Use for: API responses, computed values, rate calculations
56- Always handle cache miss (regenerate data when transient expires)
57- Delete transients when underlying data changes
58
59### WooCommerce Cache Helpers
60
61- `WC_Cache_Helper` — manages WooCommerce-specific caching
62- `wc_get_transient_version( 'product' )` — cache versioning for products
63- Cache invalidation on product/order changes via version bumps
64
65## Database Optimization
66
67### Query Optimization
68
69- Use `wc_get_orders()` / `wc_get_products()` instead of `WP_Query`
70- Limit queries: always use `limit`/`per_page` parameters
71- Avoid `meta_query` on large tables — use HPOS custom columns instead
72- Use `'fields' => 'ids'` when you only need IDs
73- Avoid `'no_found_rows' => false` on large result sets
74
75### Index Optimization
76
77- Ensure custom tables have proper indexes on queried columns
78- WooCommerce HPOS tables include optimized indexes by default
79- For custom tables: add indexes on columns used in WHERE, JOIN, ORDER BY
80
81### Background Processing
82
83Move heavy operations out of the request cycle:
84- **Action Scheduler** — WooCommerce's job queue
85- Schedule: `as_schedule_single_action( $timestamp, 'hook_name', $args )`
86- Recurring: `as_schedule_recurring_action( $timestamp, $interval, 'hook_name', $args )`
87- Handles retries, failure logging, and concurrent execution
88
89## Frontend Performance
90
91### Asset Loading
92
93- Conditionally load CSS/JS only on relevant pages
94- Use `wp_enqueue_script` with `strategy => 'defer'` or `'async'`
95- Combine/minify assets in production
96- Use `wp_script_add_data( $handle, 'strategy', 'defer' )`
97
98### Cart Fragments
99
100AJAX cart fragment refreshing can be a bottleneck:
101- Filter `woocommerce_cart_fragments` to minimize data
102- Disable on pages where cart widget isn't shown
103- Use `wc_cart_fragments_params` localized data
104
105### Image Optimization
106
107- Use WordPress responsive images (`srcset`, `sizes`)
108- Enable lazy loading: `loading="lazy"` on product images
109- Use WebP format where supported
110- Configure image sizes: `add_image_size()` and WooCommerce image settings
111
112## Action Scheduler
113
114### Using Action Scheduler
115
116WooCommerce's built-in background job processor:
117- `as_schedule_single_action( time(), 'my_hook', $args, 'my-group' )` — run once
118- `as_schedule_recurring_action( time(), HOUR_IN_SECONDS, 'my_hook', $args )` — recurring
119- `as_enqueue_async_action( 'my_hook', $args )` — ASAP execution
120- `as_unschedule_action( 'my_hook', $args )` — cancel
121- Monitor via WooCommerce > Status > Scheduled Actions
122
123### When to Use
124
125- Sending batch emails
126- Syncing inventory with external systems
127- Generating reports
128- Processing large data imports/exports
129- Cleaning up expired data
130
131## Best Practices
132
133- Enable HPOS for new stores and migrate existing ones
134- Use persistent object cache (Redis/Memcached) in production
135- Cache expensive computations and API responses with transients
136- Use Action Scheduler for background processing — never process heavy tasks during HTTP requests
137- Profile with Query Monitor plugin to identify slow queries
138- Conditionally load assets only on pages where needed
139- Use `wc_get_orders()` / `wc_get_products()` with appropriate limits
140- Avoid N+1 query patterns — batch load related data
141
142Fetch the WooCommerce performance documentation and HPOS migration guide for exact configuration, migration steps, and optimization techniques before implementing.