If you switched on WooCommerce's High-Performance Order Storage (HPOS) and orders started acting strange — some missing from the admin list, totals not matching what your payment gateway shows, or a plugin suddenly throwing errors about order meta — you're not alone. HPOS moved order data out of wp_posts into dedicated tables, and anything that hasn't caught up with that change can leave your store in a half-migrated state. Here's how to find out what's actually wrong and get orders back in sync.

Symptom: Orders Missing, Duplicated, or Out of Sync

The usual signs after enabling HPOS (WooCommerce > Settings > Advanced > Features):

  • Orders that exist in the customer's account or in Stripe/Razorpay/PayPal don't show up under WooCommerce > Orders.
  • A yellow notice on the Orders screen saying something like "X orders are out of sync" or "pending sync."
  • Reports, analytics, or a custom plugin showing order counts that don't match what you see in the order list.
  • A theme or plugin throwing PHP notices like get_post_meta() returning empty on what used to work fine, or fatal errors mentioning WC_Order.
  • Order search or date filtering behaving oddly — results that were reliable before HPOS now miss records.

None of this means your order data is gone. In almost every case it's a sync or compatibility problem, not data loss — but it needs fixing before it causes real confusion for customers or your accounting.

Cause: Two Storage Systems, Not Fully in Step

Before HPOS, WooCommerce stored every order as a custom post type (shop_order) in wp_posts, with order details scattered across wp_postmeta. HPOS introduces dedicated tables — wp_wc_orders, wp_wc_order_operational_data, wp_wc_orders_meta, and a few more — built specifically for order data instead of overloading the generic posts schema.

When you first enable HPOS, WooCommerce keeps compatibility mode on by default, which mirrors every order write to both the old and new tables. That's the safety net. Problems show up when:

  • A plugin writes directly to wp_postmeta instead of going through WooCommerce's CRUD functions ($order->update_meta_data(), wc_get_orders()). That write never reaches the new HPOS tables, so the two stores drift apart.
  • The background sync process stalls. WooCommerce syncs pending records via Action Scheduler in the background. On a busy store, or a server where cron isn't running reliably, this queue can back up for hours or days.
  • You migrated a database manually (import via phpMyAdmin, a backup restore, or a host-to-host migration) and only some of the order-related tables came across, or came across at different points in time.
  • An older, unmaintained extension still assumes orders are posts and queries wp_posts WHERE post_type = 'shop_order' directly in custom SQL — that query returns nothing once HPOS is the authoritative source and compatibility mode gets switched off.

Fix: Check Sync Status First, Then Compatibility

Step 1 — Look at the built-in sync status

Go to WooCommerce > Status > Tools (or Settings > Advanced > Features on newer versions) and look for "Orders data sync." If it shows a non-zero count of orders pending sync, click Sync now. Let it finish — for a store with a large order history this can take a while, since it runs through Action Scheduler in batches rather than all at once.

Step 2 — Confirm compatibility mode is actually on

Under WooCommerce > Settings > Advanced > Features, check that "Enable compatibility mode" is ticked while you're still verifying things. Don't switch it off until the sync tool reports zero pending records and you've spot-checked a handful of recent orders manually against what your payment gateway logged.

Step 3 — Run the sync from WP-CLI (faster, and works around a stuck queue)

If you have SSH/terminal access on your SkyServer hosting plan or VPS, WP-CLI can force the sync directly instead of waiting on the background scheduler:

wp wc cot sync --batch-size=500
wp wc cot verify_db_tables

Run these from your site's document root. verify_db_tables confirms the HPOS tables exist and are structured correctly — useful if you restored a database backup and want to rule out a missing table before anything else.

Step 4 — Check which plugin is bypassing WooCommerce's CRUD

If sync completes but the same orders keep drifting out of sync again, the cause is almost always a plugin or custom code writing straight to wp_postmeta. Deactivate custom order-related plugins one at a time (payment gateways, invoicing tools, custom reporting plugins, anything that touches order data) and place a test order after each deactivation. Check the WooCommerce HPOS compatibility list for known-incompatible extensions before you spend time hunting manually — a lot of the older ones are already documented.

Step 5 — If you migrated the database manually, verify the HPOS tables came across

Open phpMyAdmin from cPanel and check that all of these exist for your site's table prefix:

TablePurpose
wp_wc_ordersCore order records (replaces shop_order posts)
wp_wc_order_operational_dataStatus, totals, currency, shipping info
wp_wc_orders_metaCustom order meta (equivalent of postmeta)
wp_wc_order_addressesBilling/shipping addresses
wp_wc_order_product_lookupUsed by WooCommerce Analytics

If any of these are missing after a restore or a manual export/import, the fastest fix is usually to temporarily disable HPOS (fall back to posts-based storage), confirm the store works normally, then re-enable HPOS so WooCommerce recreates and repopulates the tables from scratch via the sync tool — rather than trying to hand-fix table structure.

Prevention: Don't Skip Compatibility Mode

A few habits keep this from happening again:

  • Never flip off compatibility mode on day one. Run in dual-write mode for at least a week on a store with real order volume, and confirm the sync tool consistently reports zero pending.
  • Update WooCommerce extensions before you migrate, not after. Most actively maintained plugins added HPOS support in 2023–2024 releases; an outdated version is the most common cause of silent drift.
  • Take a full database backup immediately before enabling HPOS — through cPanel's Backup Wizard or a manual mysqldump over SSH — so a rollback is a restore, not a rebuild.
  • If you're migrating stores to SkyServer, run the sync tool and wp wc cot verify_db_tables as a standard step right after the database import, before you point DNS at the new server or go live.
  • Keep an eye on Action Scheduler (Tools > Scheduled Actions, if the plugin is active, or WooCommerce > Status > Scheduled Actions) — a backlog there is often the first sign that syncing has stalled, before it shows up as missing orders.

Frequently Asked Questions

Will disabling HPOS delete my order data?

No. Turning HPOS off switches WooCommerce back to reading orders from wp_posts, but the HPOS tables aren't dropped automatically. Any order created only in HPOS after compatibility mode was switched off, however, needs to be synced back before you disable it — otherwise those specific orders won't show up in the posts-based view.

How long does the initial sync take for a large store?

It depends on order volume and server resources, but figure on roughly 500–1,000 orders per batch cycle through Action Scheduler. A store with 50,000 historical orders can take several hours running in the background, or a few minutes if you force it with wp wc cot sync over SSH with a larger batch size.

Is HPOS safe to enable on a live, active store?

Yes, as long as you leave compatibility mode on during the transition and verify sync status before turning it off. WooCommerce designed HPOS to be enabled without downtime — the risk isn't the migration itself, it's disabling compatibility mode too early while an incompatible plugin is still writing to the old tables only.

My custom report plugin stopped showing recent orders — is that HPOS?

Very likely. Any custom code or older plugin querying wp_posts WHERE post_type = 'shop_order' directly will return nothing for orders created after HPOS became authoritative. The fix is on the plugin's side — it needs to use wc_get_orders() or the WC_Order_Query class instead of raw SQL against the posts table.

Can I check sync status without opening wp-admin?

Yes — wp wc cot sync --batch-size=500 will report pending record counts and process them from the command line, which is faster than clicking "Sync now" repeatedly in the dashboard, especially over SSH on a SkyServer VPS.