September 4, 2026 · Vedanshu Jain
WooCommerce HPOS Migration: A Step-by-Step Guide for High-Volume Stores
A WooCommerce HPOS migration guide for high-volume stores: what changes, compatibility mode, plugin checks, WP-CLI steps, rollback, and what to measure.
A WooCommerce HPOS migration moves your orders out of wp_posts and wp_postmeta into four purpose-built tables, and on a store with hundreds of thousands of orders it is the largest database performance change available. Done in order — audit plugins, enable compatibility mode, sync, verify, switch, then drop the sync — it is reversible at every step.
What HPOS changes
Before High-Performance Order Storage, every order was a post of type shop_order, and every field you care about — billing address, totals, payment method, customer ID, status history — was a row in wp_postmeta. Filtering orders by customer meant joining a table that also held every product attribute, page setting, and plugin note on the site. HPOS replaces that with four tables: wp_wc_orders, wp_wc_order_addresses, wp_wc_order_operational_data, and wp_wc_orders_meta, with typed columns and dedicated indexes on status, creation date, and customer (source).
The performance difference is not subtle. WooCommerce’s own benchmark on a store with about 400,000 orders and 30,000 products found that creating 1,000 orders took 15.18 s under HPOS versus 78.12 s on posts storage (about 5× faster), a metadata search across 1,000 orders took 0.053 s versus 0.639 s (about 10×), and filtering by customer took 0.016 s versus 0.599 s (about 40×). Checkout itself was about 1.5× faster (source). Urumi co-founder Vedanshu Jain led HPOS at Automattic.
HPOS has been enabled by default for new installations since WooCommerce 8.2 in October 2023; existing stores have to opt in (source). If your store predates that and nobody has flipped the switch, you are still on posts storage.
Compatibility mode and sync
Two settings under WooCommerce > Settings > Advanced > Features control the migration. “Order data storage” chooses which store is authoritative — posts (legacy) or HPOS. “Enable compatibility mode (synchronizes orders to the posts table)” keeps both stores populated: every order write goes to the authoritative store and is then copied to the other. Turning compatibility mode on schedules two Action Scheduler jobs, wc_schedule_pending_batch_process to find orders that need backfilling and wc_run_batch_process to copy them 25 at a time, rescheduling until the tables match (source).
Compatibility mode is what makes the migration safe: while it is on you can switch the authoritative store in either direction without losing data. It also doubles every order write, so treat it as a transitional state, not a permanent one.
One change from this year matters for anyone who left compatibility mode on. Since WooCommerce 10.7 (April 2026), “sync on read” is disabled by default. Previously, if a plugin wrote directly to wp_postmeta, HPOS could pick that change up on the next read and overwrite its own record; that could revert order statuses or restore stale data. WooCommerce now treats the posts copy as read-only, and stores that were relying on that behavior see a one-time admin notice after upgrading (source). If any custom code still writes order data through update_post_meta, those writes are now silently lost. That is the strongest argument for finishing the migration rather than living in compatibility mode.
How to check plugin compatibility
A plugin is HPOS-compatible when it declares itself so on the before_woocommerce_init hook with FeaturesUtil::declare_compatibility( ‘custom_order_tables’, __FILE__, true ), and when its code actually uses the WooCommerce order API rather than WordPress post functions. The patterns that break under HPOS are get_post(), get_post_meta(), update_post_meta(), WP_Query for shop_order, and direct $wpdb queries against wp_posts or wp_postmeta for order data. The replacements are wc_get_order(), wc_get_orders(), the $order->get_meta() / update_meta_data() / save() chain, and OrderUtil::custom_orders_table_usage_is_enabled() when a plugin genuinely needs to branch (source).
Three ways to audit. The Features screen links to a filtered plugin list at /wp-admin/plugins.php?plugin_status=incompatible_with_feature&feature_id=custom_order_tables, and WooCommerce refuses to switch the authoritative store while anything on that list is active (source). From the command line, wp wc hpos status gives an overview and wp wc hpos enable warns about incompatible plugins before doing anything (source). And for custom code — theme functions, mu-plugins, agency snippets, ERP connectors — grep for the broken patterns above, because nothing declares compatibility on your behalf.
The dangerous case is a plugin that has declared compatibility but still writes raw postmeta somewhere; only a code read or a data verification after sync will find it.
Migration steps
- Back up, and rehearse on staging. Take a full database backup you have actually restored once. Run the whole procedure on a staging copy with production data first; the time it takes there tells you how long production will take.
- Clear the incompatible list. Update, replace, or patch every plugin flagged on the Features screen. Keep extensions that store their own data as custom post types (Subscriptions, Bookings) active throughout; WooCommerce’s documentation warns that deactivating them mid-migration causes data discrepancies (source).
- Enable compatibility mode. Posts storage stays authoritative; the backfill starts in the background. On a large store, run the sync from WP-CLI instead of waiting for Action Scheduler: wp wc hpos sync processes orders in batches and reports progress, and wp wc hpos count_unmigrated tells you how many remain (source). Run it in a screen or tmux session; a million-order store can take hours.
- Verify. wp wc hpos verify_data compares both stores and lists mismatches; –re-migrate fixes them in place. wp wc hpos diff <order_id> shows the field-level difference for any order that fails.
- Switch. Select “High-performance order storage” as authoritative with compatibility mode still on. Watch the admin order list, order edit, REST, and every integration that reads orders for at least one full business cycle; a week is reasonable.
- Drop the sync. Turn off compatibility mode so each order is written once. Only after that, and only once you are certain nothing reads posts storage, wp wc hpos cleanup removes the legacy copies and reclaims wp_postmeta space. WooCommerce’s benchmark store expected to eliminate about 97% of its postmeta rows this way (source).
Rollback
As long as compatibility mode was on when you switched, rollback is a settings change: select “WordPress posts storage (legacy)” as authoritative, and the posts tables are already current. If you had already turned compatibility mode off, turn it back on first, wait for count_unmigrated to reach zero in the reverse direction, verify, then switch (source). The one irreversible step is cleanup. After it runs, rolling back means resyncing from HPOS into empty posts tables, which works but is slow, and anything the legacy tables held that HPOS did not know about is gone. That is why cleanup is last and not part of the switch itself.
What to measure before and after
Capture these on production for a week before you switch, then again a week after, using the same tooling:
- Server time for the admin orders list (edit.php?post_type=shop_order before, admin.php?page=wc-orders after) with a status filter and a customer search, at p50 and p95.
- Order edit page load time and save time — this is where support staff and fulfillment feel the difference.
- Checkout order-creation time from the APM trace, from the checkout POST or Store API call to the redirect.
- REST GET /wc/v3/orders?per_page=100 response time; WooCommerce 10.8 added cache priming for HPOS order queries specifically to remove N+1 patterns in REST serialization (source), so measure on 10.8 or later.
- Row counts and on-disk size for wp_posts, wp_postmeta, and the four wc_order* tables.
Analytics tables are unaffected by the storage switch, so reporting numbers should be identical; if they are not, a plugin is writing orders outside the API.
Common failures
- The sync never finishes. Action Scheduler runs on WP-Cron, which only fires on page views, and the batch is 25 orders. On a large store, run wp wc hpos sync from a real shell and put Action Scheduler on a system cron.
- Verification finds mismatches on a handful of orders. Usually a plugin that wrote raw postmeta after the batch copied that order. Fix the plugin, then verify_data –re-migrate.
- Status changes revert or stale data reappears. This is the sync-on-read problem the 10.7 change was made to stop; something is still writing to the posts copy. Find it with a database query log filtered to wp_postmeta writes during an order edit.
- Custom order fields vanish from the edit screen. A meta box reading get_post_meta( $post_id ). Rewrite it against the order object; the meta itself is in wc_orders_meta and has not been lost.
- Compatibility mode left on for a year. Every order costs two writes, the postmeta table keeps growing, and the store never gets the performance it migrated for. Schedule the turn-off.
How Urumi handles this
Urumi is the platform layer for WooCommerce stores doing $1M–$50M in GMV, where order volume is high enough that storage choices show up in support-team hours and checkout latency. The migration above runs against an isolated staging copy of production first, with the fully managed APM capturing before-and-after traces for order list, order edit, and checkout, and the production switch sits behind 30-day point-in-time recovery, so rollback does not depend on compatibility mode alone. Do Amore, a custom engagement-ring brand, came to Urumi with order edits taking 8.1 s; after migration they take 0.67 s, with every custom plugin intact and zero downtime during the move. Ships, the Builder AI, handles the plugin patches this guide asks you to grep for — features and third-party integrations from plain English, tested, through your review pipeline, one click from rollback. Already have a team or an agency? They ship faster with the grunt work covered. See the Urumi WooCommerce hosting platform.
Frequently asked questions
Is a WooCommerce HPOS migration reversible?
Yes, as long as compatibility mode is on when you switch: choosing “WordPress posts storage (legacy)” as the authoritative store reverts instantly. The only irreversible step is wp wc hpos cleanup, which deletes the legacy copies, so run it last and only after a full verification cycle.
How long does an HPOS migration take?
The background sync copies 25 orders per Action Scheduler batch, which is fine for small stores. For hundreds of thousands of orders, run wp wc hpos sync from WP-CLI; expect hours rather than minutes, and rehearse on staging to get a real estimate.
Do I need to keep compatibility mode on after switching to HPOS?
Keep it on for a monitoring window — a week or one business cycle — then turn it off. Left on permanently, it doubles every order write and, since WooCommerce 10.7 disabled sync on read, no longer protects you from plugins that write raw postmeta anyway.
How do I know if a plugin is HPOS-compatible?
Check the “View and manage” list on WooCommerce > Settings > Advanced > Features, or run wp wc hpos status. For custom code, search for get_post_meta, update_post_meta, and WP_Query on shop_order; those must be replaced with the WooCommerce order API.
Read how the migration fit into a larger platform move in the Do Amore case study, and see what else belongs in the stack in what managed WooCommerce hosting must include.
Last reviewed September 2026. Competitor details come from their public pages on the dates linked; check them before you buy.
Built by the people who built WooCommerce core.
We built WooCommerce core at Automattic — the parts that matter in production: performance, payments, reliability. Earlier, engineering at HackerRank (Y Combinator) through its enterprise scale-up. Naman led Payments and WooCommerce releases to 4.5M merchants; Vedanshu led HPOS, Taxes, and Shipping. Run by AI, overseen by the people who built WooCommerce core.
Grow your store's revenue on Urumi.
The AI platform D2C brands use to grow revenue — built by the people who built WooCommerce core.
See the WooCommerce platform · Start your WooCommerce store on Urumi · Talk to the founders
Agent live · 99.99% uptime · shipping today.