How the interviewer opens it
“Design a bank's wire transfer API. Customers should be able to move money between accounts, including accounts at other banks, without moving it twice. We need a correct ledger and a clear way to see what happened to a transfer.”
The prompt is vague on purpose. The first few minutes are yours: narrow it to the core features and agree on the numbers before you draw anything.
What to clarify first
- Accounts and transfer types
- Scale
- Read:write mix
- Latency
- Consistency and availability
- Retry contract
- External banking interface
- Balances and pending funds
- Durability and audit
- Authorization and exclusions
The answers stay with the interviewer. In a SysRound round, Alex answers them as an interviewer would.
Scope of a strong answer
Core requirements
- Create transfers between our accounts and outbound transfers to another bank
- Prevent overdrafts and duplicate financial effects while maintaining a balanced, auditable ledger
- Expose transfer status and make client retries safe
- Recover and reconcile outbound transfers, including confirmed failures and full returns
Usually out of scope
- Foreign exchange, fees, scheduled transfers, and partial returns
- Unrelated incoming wires
- Building a banking network or payment processor
- Implementing identity verification, fraud models, or sanctions screening
What interviewers probe
- Atomic money movement and ledger invariants
- An individually balanced journal can still overdraw a customer, and a correct balance check can still lose money if balance updates, postings, and transfer state commit separately.
- Client retries and the scope of exactly once
- A client cannot tell whether a timed-out request committed. Deduplication must survive concurrency, crashes, and long retention without confusing repeated intent with repeated delivery.
- The uncertain boundary with another bank
- The local database and the banking partner cannot share an atomic commit. A successful external submission can look exactly like a failed one to the caller.
- Settlement, returns, and reconciliation
- An accepted instruction is not proof of cash movement. The ledger must eventually match external settlement evidence while preserving the history of failures and later returns.
Common mistakes
- Treating exactly once as a property supplied by HTTP, a queue, or a distributed lock rather than a business invariant across retries.
- Conflating accepted, submitted, and settled, or treating an unknown external outcome as a failure.
- Maintaining balances, ledger postings, transfer state, and dispatch work through unrelated writes.
- Releasing reservations on a timer even when the partner may already have executed the wire.
- Using floating-point money, mutable ledger entries, or compensation that deletes the original transaction.
- Starting with independently sharded debit and credit services at a few hundred writes per second, creating a distributed transaction problem before it is needed.
The bar by level
- Senior (L5/E5)
- Owns the complete outbound lifecycle: atomic reservation plus outbox, stable partner instruction IDs, guarded status transitions, safe retries, settlement and return postings, and reconciliation. Can walk through concurrent requests and crash windows without losing or duplicating money, while choosing a simple transactional architecture for the given scale.
- Staff (L6+/E6+)
- Defines the exact guarantee and its limits at both client and partner boundaries. Separates financial state from knowledge of external execution, addresses retained deduplication and ledger growth, and designs recovery when partner guarantees or regional availability fail. Explains operational ownership of unresolved funds, reconciliation breaks, and audited repairs without trading correctness for an optimistic status.