Katkat

Design an Idempotent Double-Entry Ledger

StripeSoftware Engineer · Technical Screen

Last updated

Design a highly reliable, idempotent double-entry ledger system that guarantees strict consistency, append-only immutability, and supports high-concurrency writes on hot accounts.

Scenario

You are tasked with designing the core Double-Entry Ledger service for a global financial platform. The ledger records every movement of funds between user accounts, internal reserve accounts, and partner settlement accounts. Because clients make requests over unreliable networks, the service must guarantee idempotency and maintain strict correctness guarantees under network retries and concurrent executions.

Functional Requirements

  1. Double-Entry Invariants: Every transaction must contain two or more balanced entry legs where sum(debits) == sum(credits) for each currency.
  2. Strict Idempotency: Callers provide a unique Idempotency-Key. Retries with the same key must return the exact same response without creating duplicate postings.
  3. Pending and Posted States: Support multi-phase transactions (e.g., hold/authorize funds as pending, followed by capture/settle or void/cancel).
  4. Auditability & Immutability: Ledger records are append-only. Corrections or adjustments must be executed via explicit reversing transactions.
  5. Balance Inquiries: Query current settled, pending, and available balances for any account as of a specified point in time.

Non-Functional Requirements

  • Strict Consistency (ACID): Zero tolerance for phantom money creation, unbalanced entries, or overdrafts on non-credit accounts.
  • Availability & Latency: 99.99% write availability with p99 write latency under 50ms.
  • Scale:
    • 10,000 transaction requests/second at peak.
    • 50,000 balance query requests/second at peak.
    • Several billion transaction records retained for 7+ years.
    • Hot accounts (e.g., platform fee collections or merchant clearing accounts) can experience 500+ concurrent writes/second.

What Your Design Should Cover

  • Data Model: Core schema for transactions, entries, accounts, and idempotency records.
  • Idempotency Strategy: Exact mechanism used to detect and safely deduplicate retried or concurrent requests.
  • Concurrency & Hot Accounts: How to avoid database row lock contention on frequently updated system accounts while preventing race-condition overdrafts.
  • Balance Computations: Strategy to provide sub-10ms balance queries without scanning millions of historical immutable rows.

Hints

Hint 1

Tie the idempotency record creation to the ledger transaction within the same atomic database transaction boundary.

Hint 2

Avoid re-aggregating every historical entry on each balance query by maintaining materialized balance snapshots combined with incremental deltas.

Hint 3

Hot accounts can be partitioned into multiple virtual sub-accounts internally, aggregating balances on read and distributing writes across slots.

Follow-up questions

  • How does your design handle asynchronous external reconciliation discrepancies (e.g., bank settlement statements disagreeing with internal ledger records)?
  • If an account requires a strict non-negative balance constraint, how does distributing that account across virtual sub-accounts affect balance checks?
  • How would you architect multi-region active-active writes without risking split-brain ledger states or balance violations?