The Problem
A client called me last Friday in a panic. Their WooCommerce store had migrated to High-Performance Order Storage three weeks earlier, the front end was fine, the order list was fine, the emails were fine. The WooCommerce → Analytics → Overview dashboard was showing 0 orders, $0 revenue, 0 customers. Filter to "Last 30 days": zero. "Last 7 days": zero. "Today": zero, despite seven orders processed that morning.
The old Reports screen under WooCommerce → Reports still had numbers. The Orders table had every order in it. The Analytics screen, the one the marketing team uses every morning, was a blank graph and a row of zeros.
There were no console errors, no PHP warnings in the log, no failed cron jobs in Action Scheduler. The admin notice at the top of the Analytics page said "Your store data is updated" with a green tick. That tick was the most expensive lie in the store.
Why It Happens
WooCommerce Analytics does not query the live orders. It queries a set of lookup tables that get populated by a background job whenever an order changes: wp_wc_order_stats, wp_wc_order_product_lookup, wp_wc_order_tax_lookup, and a few others. The Reports screen reads from wp_posts and wp_postmeta directly, which is why it kept working. Analytics is a separate denormalised store, and HPOS migrations break the bridge.
The migration tool moves the canonical order data from wp_posts into wp_wc_orders, flips the authoritative store flag, and stops writing the legacy tables in the same transaction. The Analytics lookup tables are populated by a hook that, in older versions, was wired to the legacy save_post_shop_order action. After HPOS is authoritative that action stops firing on new orders, so nothing gets written into wp_wc_order_stats. Existing rows from before the migration stay where they are, but rows for any order placed after the cutover never appear. If you also ran the "delete legacy data" step at the end of the wizard, the old rows get truncated too and the dashboard goes to absolute zero.
The HPOS migration guide mentions in a sidebar that Analytics needs to be regenerated. It does not mention that the regeneration job is not queued automatically when you enable HPOS through the Settings → Advanced → Features toggle, only when you go through the Tools → Database wizard. Most stores I have seen toggle it through Settings.
The Fix
The fix is to rebuild the Analytics lookup tables from the HPOS data and make sure new orders get written into the tables going forward. Three steps.
Step 1: Trigger a full Analytics rebuild from WP-CLI. The admin UI option to rebuild is buried under Status → Tools → Rebuild customer and order lookup tables, but it times out on stores with more than a few thousand orders. Use the CLI instead:
wp wc tool run regenerate_order_stats_table --user=1
wp wc tool run regenerate_order_product_lookup_table --user=1
These run synchronously and stream progress to stdout. On a 40k order store the first one took about six minutes, the second about ten. If the tool name is rejected on your version, list what is available with wp wc tool list --user=1 and look for the entries that match.
Step 2: Confirm the rebuild scheduler is actually running. WooCommerce 9.5 and later replace the synchronous rebuild with an Action Scheduler job that processes orders in batches. If Action Scheduler is wedged, the rebuild will appear to complete but the tables will only get a partial fill. Check for stuck jobs:
wp action-scheduler run --hooks=wc-admin_import_orders --batch-size=50
wp action-scheduler run --hooks=wc-admin_import_customers --batch-size=50
Repeat until each command reports 0 actions found. If Action Scheduler reports actions stuck in "in-progress" state from more than 10 minutes ago, that is a separate bug. See my note on stuck Action Scheduler jobs.
Step 3: Wire the rebuild into the HPOS write path. This is the part the migration wizard skips. New orders need to populate the lookup tables on creation, not on the next nightly cron sweep. The cleanest fix is to make sure your store is on WooCommerce 9.4.2 or later, where the Analytics writer is hooked into woocommerce_new_order and woocommerce_update_order directly. On older versions, you can add this to a mu-plugin:
add_action('woocommerce_new_order', function ($order_id) {
if (! class_exists('\Automattic\WooCommerce\Admin\API\Reports\Cache')) {
return;
}
\Automattic\WooCommerce\Admin\API\Reports\Cache::invalidate();
do_action('wc-admin_import_orders', $order_id);
}, 99, 1);
add_action('woocommerce_order_status_changed', function ($order_id) {
if (! class_exists('\Automattic\WooCommerce\Admin\API\Reports\Cache')) {
return;
}
\Automattic\WooCommerce\Admin\API\Reports\Cache::invalidate();
do_action('wc-admin_import_orders', $order_id);
}, 99, 1);
This invalidates the Analytics report cache and queues the order for import on the next Action Scheduler tick. The priority 99 makes sure it runs after the core HPOS writer has committed the row.
Verify with a real SQL check. After the rebuild and a test order, query the stats table directly:
SELECT COUNT(*) FROM wp_wc_order_stats WHERE date_created >= NOW() - INTERVAL 1 DAY;
The count should match the orders placed in the last 24 hours. If the count is lower, an order was written to HPOS but never to Analytics, and Step 3 is not firing. If the count is higher, you have duplicates from a double-import, so clear with wp wc tool run regenerate_order_stats_table again.
The Lesson
The Analytics dashboard is a separate denormalised store from the orders table. HPOS migrations move the orders but the lookup tables that Analytics reads from are not automatically rebuilt or kept in sync. Run the regeneration jobs from WP-CLI, drain the Action Scheduler queue, and make sure new orders are wired into the import hook. The dashboard zeros are not a display bug, they are a write bug, and the green admin notice means nothing.
If your store migrated to HPOS and your marketing team is now flying blind on numbers, that is the kind of audit I run for clients. See my services. For a related HPOS gotcha on bulk operations, read WooCommerce HPOS bulk status update failing.
Analytics blank after an HPOS migration? Let me fix it.