XTRACKER

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:

Delivery pipeline

  • 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