The deposit you almost counted twice
A story about exactly-once tracking: how retries and re-fired postbacks silently inflate (or lose) revenue, and how dedup + a durable outbox keep your numbers honest.
A partner's postback fires when a user deposits. Then their system retries it — twice — because of a status change. Now your dashboard shows three $25 deposits. You scale the "winning" campaign on phantom revenue. A week later you reconcile with the network and you're $4,000 short of what your tracker claimed.
This is the quiet killer of ad optimization: data you can't trust. Here's how to make it trustworthy.
Where the double-counts come from
Every layer in the chain retries:
- Networks re-fire postbacks on retries and status changes.
- Your app retries on a timeout — but did the first request actually fail, or just the response?
- The delivery worker retries failed dispatches to Meta/your webhook.
Without protection, each retry is a new "conversion." Revenue inflates, your cost-per-deposit looks amazing, and you pour budget into a mirage.
The fix: an external event id
Send an eid — your unique id for the conversion (the network's trade/transaction id) — on every registration and deposit:
…&event=deposit&uid=abc&value=25&eid=tx-42 (10:00:00) → queued
…&event=deposit&uid=abc&value=25&eid=tx-42 (10:00:07) → duplicate ✓
…&event=deposit&uid=abc&value=25&eid=tx-42 (10:01:13) → duplicate ✓
The first call records the deposit. Every re-fire with the same eid returns duplicate and changes nothing — regardless of when it arrives. Three postbacks, one deposit, correct revenue. (The deep mechanics are in Idempotency, in depth.)
The other failure mode: lost deposits
Double-counting inflates; the opposite is worse. If a destination is down when a deposit fires and the event is fire-and-forget, that conversion is gone — and Meta never learns to find you more depositors.
XTRACKER writes every event to a durable inbox before anything else, then fans it out to a per-destination outbox that retries with backoff until it lands. A Redis blip, a worker restart, or a 30-second Meta outage doesn't lose the deposit — it lands once, when the destination recovers.
Why this is a growth lever, not just hygiene
Your entire optimization loop runs on these numbers:
- If revenue is inflated, you scale losers and waste spend.
- If revenue is lost, your pixel can't optimize and your CPA creeps up.
- If revenue is exactly right, every decision you make compounds correctly.
Accurate data isn't a compliance checkbox — it's the foundation the whole funnel optimization sits on. Garbage in, garbage scaled.
The one-line takeaway
Send an eid on every conversion. Let the outbox handle delivery. Then trust your dashboard enough to bet your budget on it.
Next
- Idempotency, in depth — the dedup key and
eidvs time. - Optimize creatives — what trustworthy numbers let you do.
- Destinations — durable delivery and retries.
Keep reading
How to find and fix the leak in your funnel
A practical walkthrough: use the funnel breakdown and conversion gauge to pinpoint exactly where users drop off, form a hypothesis, fix one thing, and measure the lift.
PlaybookKeep your finger on the pulse: real-time conversion monitoring
A live dashboard isn't a vanity metric — it's an early-warning system. Here's how watching conversions in real time catches broken funnels and dead campaigns before they burn your budget.
PlaybookSame budget, more deposits: optimizing creatives with per-link data
Clicks lie. Deposits don't. Use per-link attribution to see which creative actually drives revenue — then move spend to the winner and kill the losers.