Design an Idempotent Double-Entry Ledger
Company: Stripe
Role: Software Engineer
Category: System Design
Difficulty: medium
Interview Round: Technical Screen
Design a ledger service that records financial transactions using double-entry accounting. Clients submit operations over an unreliable network and may retry the same logical request. The design must ensure that retries do not create duplicate postings while unrelated requests continue normally.
Focus on the idempotency-key contract as well as account, transaction, and posting models; atomic writes; balance queries; concurrency; reconciliation; and operational recovery.
### Constraints & Assumptions
- One ledger transaction contains two or more postings whose signed amounts sum to zero per currency.
- Posted entries are immutable; corrections use compensating transactions.
- Clients choose idempotency keys within an authenticated scope.
- A timeout does not tell the client whether the original request committed.
- The initial database supports serializable transactions or equivalent row and uniqueness constraints.
### Clarifying Questions to Ask
- Is the idempotency key unique per account, API credential, customer, or entire ledger?
- How long must completed idempotency records be retained?
- Can a transaction remain pending, and can pending funds affect available balance?
- What throughput, currency, and audit requirements apply?
### What a Strong Answer Covers
- Defines an immutable balanced posting model and a separate transaction state.
- Scopes idempotency keys, binds them to a canonical request hash, and stores the response atomically with the write.
- Handles concurrent identical requests and key reuse with different payloads.
- Uses one transaction for validation, postings, balance projection, and idempotency completion.
- Explains pending versus posted balances, reversals, reconciliation, and restore behavior.
- Identifies hot-account contention, sharding limits, and observability needs.
### Follow-up Questions
1. What should a retry receive if the first request is still in progress?
2. How would idempotency work across two services that each own part of a workflow?
3. How can the ledger scale without allowing one transaction to span arbitrary shards?
Quick Answer: Design an idempotent double-entry ledger for financial requests retried over unreliable networks. Address immutable postings, balanced currencies, concurrent requests, pending and posted states, atomic responses, balance queries, corrections, reconciliation, recovery, and hot-account scaling.