Sync lag: how to find out your data is an hour behind, and fix it
Stale data does not announce itself. Everything renders, every number looks plausible, and the flow that should have stopped when somebody bought sends anyway. Here is how to detect it and the three causes worth checking first.
An integration that is an hour behind behaves identically to one that is current, right up until a decision depends on the difference. Then somebody who ordered forty minutes ago receives a cart recovery email, a sold-out product stays in an ad, and a report is quietly wrong in a way nobody can reproduce tomorrow.
The first problem is that almost nobody measures it. The second is that when they do, they measure the wrong thing.
Measure end to end, not per hop
The number that matters is the wall-clock gap between the event happening in the shop and it being usable in your system. Not queue latency, not processing time — the whole path.
- Record the shop's own event timestamp on every record you import, separately from when you received it.
- Compute the difference and keep a rolling distribution — median and 95th percentile, not the average, which one stuck record will ruin.
- Alert on the 95th percentile, because the median stays healthy long after the tail has fallen apart.
- Measure per entity type. Orders may be seconds behind while products are hours behind, and one aggregate figure hides it.
The three causes worth checking first
- Cron that is not running. WordPress's scheduler only fires when somebody visits the site, so a quiet shop at 3 a.m. runs nothing. Anything batched behind it waits for the next visitor.
- A suppression that never lifts. Live updates suppressed during a backfill, and a backfill that stalled with no cron behind it, leaves "running" as a state nothing exits. Make suppression per entity and expire it after ten minutes of no progress.
- Payload built at the wrong moment. Hooks that fire before the record is complete —
woocommerce_new_orderfires before the order has items — produce either empty payloads or a retry loop. Queue the id and build the payload at send time.
What fast actually looks like
An order should reach the marketing system in about a second: roughly 250 ms to save in WooCommerce, then a few tens of milliseconds to send. The trick is not speed, it is ordering — the send happens after the response has been flushed to the shopper, so nobody waits for it.
- Flush the response first, then do the outbound work. On PHP-FPM that is
fastcgi_finish_request(). - Prioritise by what a shop notices. Purchases, refunds and consent changes go immediately; browsing events can wait for a sweep.
- Collapse repeated changes. Several updates to one order in a single request should produce one delivery, not four.
Where lag actually bites
- Flow exits. A cart recovery that exits on purchase is only as good as how fast the purchase arrives. An hour of lag means an hour in which the email goes out anyway.
- Stock in feeds. An out-of-stock product still being advertised is spend on something unbuyable, and a disapproval risk.
- Segments at send time. A gate evaluated against stale data excludes people who came back and includes people who left.
- Support. "I placed that order an hour ago" against a screen that has never heard of it costs trust more than it costs money.
Put it on a screen
The cheapest fix for silent staleness is making it visible. An integrations screen should say, per shop:
- Last event received, with a timestamp. Nothing detects a shop that stopped talking faster.
- Current lag, median and worst, per entity type.
- Last successful reconcile.
"Connected" as a green dot with nothing behind it is decoration. It stays green while nothing has arrived for a week.
Sources and further reading (4)
- WordPress — Plugin handbook: cron
- PHP — fastcgi_finish_request
- WooCommerce — Action and filter hook reference
- Google — Merchant Center policies (availability)
Checked on 23 September 2026. Provider prices, mailbox rules and legal guidance change — verify anything you plan to act on.
An order that arrives before the email goes out
Auralata's connector sends a purchase after the shopper's page has already finished loading, so an order reaches the app in about a second — and the integrations screen shows the last event received, per shop, with the time.