How report data is compiled
Updated September 15, 2026
A customer report is a set of totals over every order that matched its filters. There are two ways the plugin can build those totals, and it chooses between them automatically. Both produce identical figures, so the report itself does not need to know which one ran.
The lookup path
The preferred path reads the WooCommerce Analytics lookup tables. Order totals, statuses, dates, tax and item counts come from the order statistics table; payment methods, discount and shipping totals, addresses and attribution meta are read in bulk from wherever the orders are stored; and refunds are read from the refunds themselves so they match what WooCommerce reports.
Line items are read from the order item tables rather than from the Analytics product lookup, because that table rounds revenue to the store’s display precision. Reading the raw line values keeps the product, category and coupon totals exact.
This path is several times faster than reading orders. On a store-wide report covering just over 1,000 orders, compiling the figures dropped from around 2.1 seconds to 0.18 seconds.
Orders Analytics has not imported yet
Analytics imports an order a moment after checkout, so a store is usually a handful of orders behind. Rather than abandoning the fast path over a few stragglers, those orders are read individually and folded in, keeping the totals exact.
That only holds up to a point. Once more than 500 orders are missing, which is the state of a store that has never run the Analytics import, the report switches to the order walk instead. The threshold is the acreports_report_max_unsynced_orders filter.
The order walk
The fallback reads the orders themselves. Orders are loaded in batches of 100 whole objects rather than one at a time, which lets WooCommerce read them in a single pass and prime its item and meta caches. On a customer with around 920 orders this reduced a report from roughly 9,000 queries to 200.
The batch size is the acreports_report_batch_size filter. Larger batches mean fewer queries but more orders held in memory at once.
What triggers the fallback
- The order statistics table does not exist.
- With HPOS enabled, one of the order, operational data or address tables is missing.
- The statistics table could not be read.
- More than the unsynced-order threshold is outstanding.
Other details worth knowing
- Order notes across the whole report are fetched in a single query, rather than one per order.
- A line item whose product has been deleted is grouped under a product ID of zero and left out of the products table, matching how the order item itself reports it.
- Line item tax is recalculated the way
WC_Order_Item_Productdoes it, rather than read from the rounded stored value, so totals do not drift by a fraction per line. - First and latest orders are chosen by order date, so a backdated order is never reported as the newest.


