What happens to our reports when someone deletes or voids a record in the source system?
Usually nothing, which is the problem. Incremental syncs pull records changed since a timestamp, and a deleted record stops appearing rather than announcing itself. Revenue from a voided invoice or a cancelled job stays in your warehouse indefinitely. You need delete webhooks, a status field that marks voids, or a periodic key reconciliation that compares source identifiers against your own.
Deletion is invisible to a changed-since pull
Ask an API for everything modified since yesterday and it returns records. A record that no longer exists cannot be in that list. From your integration's point of view nothing happened, so your copy keeps the row forever.
This is the single most common reason a warehouse total drifts above the source total over time. The gap grows slowly, in one direction, and looks like nothing until month-end when finance disagrees with the dashboard.
Three kinds of removal, three behaviors
- Hard delete. The record is gone and the API will not mention it again. Only a key comparison against the source finds this.
- Void or soft delete. The record remains with a status marking it void or inactive. This is the friendly case, provided your sync actually reads the status field and your reporting filters on it.
- Cancellation or reschedule. The record is legitimately real and should stay, but must not count as completed revenue. This is a modeling decision, not a sync problem, and it is frequently missed.
The key reconciliation sweep
Periodically, pull the identifier list for a closed date window from the source and compare it to yours. Identifiers you hold that the source no longer lists are removals.
Mark them as removed rather than deleting your rows. Keeping the record with a removed flag and a timestamp preserves the audit trail, which matters when someone asks why last month's total changed. It also lets you distinguish an intentional void from a sync gap, since a genuine gap tends to appear in contiguous blocks while real deletions are scattered.
Why this matters more than it sounds
Voided invoices inflate revenue. Cancelled jobs inflate completion rates. Deleted duplicate customers inflate customer counts. Each one bends the metrics that get used for staffing, commission and marketing spend decisions.
It also affects anything written on top of the data. An AI analyst summarizing the week will cite the voided invoice as revenue, because from its perspective the row exists and looks legitimate. Reconciliation before generation is not optional when the output is going to be read as fact, which is why it runs ahead of every revenue report we produce.
If you inherit a warehouse that has never reconciled keys, expect the first sweep to find years of accumulated removals at once. That is a one-time restatement worth doing deliberately, with a note explaining why last year's totals changed, rather than letting it surface during an audit.
Topics: deletes · voids · reconciliation · sync design
Have a version of this question about your own business?
The useful answer usually depends on which systems you run and how they're connected. That's a conversation, not a blog post.