Diagnosing WooCommerce HPOS Failures: Missing Orders, Blank Admin Screens, and Broken Custom Queries
Diagnose WooCommerce HPOS failures: blank order screens, missing custom queries, and migration conflicts. Compare wc_get_orders with posts-table reads and fix data access using supported APIs.
19 Jul 2026, 08:24 UTC

The problem: HPOS changes where order data lives
High-Performance Order Storage (HPOS) moves WooCommerce order records out of the standard WordPress posts table into dedicated order tables. That change improves performance, but it breaks any code that still reads or writes the shop_order post type directly. The useful takeaway: if order screens, custom queries, or reports misbehave right after enabling HPOS or during migration, the first thing to check is whether your code is reading from the old storage location instead of the supported order APIs.
Recognizable condition
You likely have an HPOS integration problem if one or more of the following appears after enabling HPOS, running a migration, or updating WooCommerce:
- Order admin screens are blank, slow, or show fewer orders than expected.
- Custom code using
WP_Queryor direct SQL onshop_orderreturns no results. - Checkout completes and payment is captured, but orders are missing from the admin list or reports.
- Reporting totals disagree with what the order list shows.
- Saving an order in the admin throws a fatal error or silently drops fields.
Cause and diagnostic table
| Symptom | Likely cause | Diagnostic |
|---|---|---|
Missing orders in WP_Query | Code still queries the posts table for shop_order | Compare wc_get_orders() IDs with a posts query |
| Blank admin list | HPOS data store/index issue or incompatible plugin | Check WooCommerce logs and HPOS state |
| Fatal on save | Plugin or theme uses removed post fields/hooks | Stack trace plus plugin isolation |
| Duplicate orders | Dual-write/backfill conflict | Compare counts and timestamps in order tables |
Ordered checks to isolate the failure
- Record your baseline. Note the exact WooCommerce, WordPress, and PHP versions, whether HPOS is enabled, and whether a migration is in progress or completed. HPOS defaults and table names have changed across releases, so the installed version matters.
- Reproduce on staging. Clone production to a staging site with a current backup. Disable all plugins except WooCommerce and switch to a default theme. If the symptom disappears, an extension is involved.
- Compare API results with posts-table reads. On staging, run the diagnostic snippet below with WP-CLI from the WordPress root (
wp eval-file diagnostic.php). This requires shell access and file-read permissions. Alternatively, load the code through a temporary must-use plugin. Do not run untested PHP against production order data.
// diagnostic.php — run with WP-CLI: wp eval-file diagnostic.php
$api_ids = wc_get_orders([
'return' => 'ids',
'limit' => 5,
]);
$post_ids = get_posts([
'post_type' => 'shop_order',
'posts_per_page' => 5,
'fields' => 'ids',
]);
echo "API order IDs: " . implode( ', ', $api_ids ) . "\n";
echo "Posts-table IDs: " . implode( ', ', $post_ids ) . "\n";
Expected check: With HPOS active, $post_ids may be empty or stale while $api_ids contains valid orders. That difference confirms the breakage is in the data access layer, not in order creation itself.
- Inspect logs and tables. Enable
WP_DEBUGand WooCommerce logging inwp-config.php. Checkwp-content/uploads/wc-logs/for fatal errors during order save. Look at the HPOS order tables directly (read-only) to confirm records exist. - Isolate the smallest reproduction. Re-enable plugins one by one and retest. Narrow the failure to a single plugin, theme template, or custom snippet.
- Test the full lifecycle. Create an order, add products, capture payment, change status, and issue a refund. Verify totals at each step.
Fixes tied to each finding
Custom code returns no shop_order results
Replace direct WP_Query, get_posts(), or raw SQL against shop_order with the supported query and CRUD APIs:
wc_get_orders()for filtered lists and counts.WC_Order_Querywhen you need programmatic query construction.wc_get_order( $order_id )to load a single order object.
For writes, use the order CRUD methods and data-store APIs rather than wp_update_post() or direct table inserts.
Reports disagree with the order list
Stop aggregating revenue or order counts from postmeta SQL. Use the reporting and analytics APIs WooCommerce provides, or query through wc_get_orders() with the appropriate date and status parameters.
Blank admin list or fatal on save
If the stack trace points to a third-party extension, contact the vendor. If the extension is incompatible and no fix exists, disable HPOS in production until the vendor ships an update. A compatibility toggle, where present in your version, is a bridge for legacy code—not a target for new integrations.
Migration-specific recovery
If symptoms appear during or after an HPOS migration, do not hand-edit order tables. Use the supported migration and backfill tools for your installed WooCommerce version, then re-run the count comparison from step 3 above. Treat manual SQL as last-resort recovery only after a tested backup and only to diagnose the problem, never as a permanent patch.
When to escalate
Handle the issue internally only when it is clearly a code-level incompatibility you can patch. Escalate to the extension vendor, your hosting provider, or WooCommerce support when:
- Orders are lost or duplicated.
- Payment gateway or webhook totals disagree with stored order totals.
- The issue cannot be reproduced on a clean staging environment.
- Core WooCommerce or a paid extension is implicated.
- The database shows corruption or duplicate keys in the order tables.
When escalating, include the WooCommerce status report, HPOS state, exact version numbers, relevant log excerpts, and a minimal reproduction case.
Limitations and verification
HPOS behavior, default enablement, custom table names, and compatibility toggles are version-sensitive and have changed across releases. Confirm the exact behavior in your installed WooCommerce version before relying on any assumption. After applying fixes, verify by reproducing the original symptom with HPOS enabled and disabled using the same order IDs and checkout flow. Re-run the count comparison, confirm the full order lifecycle succeeds, and recheck after any WooCommerce, extension, theme, or PHP update—HPOS compatibility can regress.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.