Balance Drift
Balance drift is the gap between what your counter says and what actually happened. It accumulates silently over time through retries, duplicate events, race conditions, and silent corrections.
Every system built on a plain UPDATE balance = balance - amount query experiences drift. The problem isn’t the logic — it’s the data model. A single mutable counter has no memory of how it got to its current value.
Common causes
Network retries
A client fires a deduction request. The server processes it but the response times out. The client retries. The deduction runs twice. Your user now has half the credits they should.
Duplicate webhooks
Your upstream fires the same event twice (Stripe does this, Kafka does this, every queue does this under failure). Without deduplication at the ledger level, both land.
Race conditions
Two concurrent requests read balance=1000, both deduct 100, both write back 900. Net result: 900 instead of 800. One deduction disappeared.
Silent corrections
An engineer fixes a wrong balance with a direct SQL UPDATE. The history is gone. If a user asks what happened to their credits, you have no answer.
How Trancent prevents drift
Trancent eliminates drift by enforcing idempotency at the ledger level (externalId deduplication), requiring sum-zero entries (no balance appears from nowhere), and making the journal append-only (no silent updates).