Katkat

Design a Scalable Idempotent Ledger Service

StripeSoftware Engineer · Technical Screen

Last updated

Design a high-throughput, fault-tolerant double-entry ledger service featuring immutable postings, strict write idempotency, and tunable balance freshness.

Scenario

You are tasked with designing the core internal double-entry ledger service for a global financial platform. The ledger is the single source of truth for all monetary movements between merchant accounts, consumer wallets, and platform fee accounts.

Every financial event must adhere strictly to double-entry bookkeeping rules: entries are immutable, every transaction consists of at least two postings, and the sum of debits must equal the sum of credits. The system must never double-count transactions despite network retries and must handle extreme traffic spikes to centralized accounts without cascading lock contention.

Requirements

Functional Requirements

  • Double-Entry Transactions: Atomic execution of multi-legged transactions (credits and debits must sum to zero). Entries are append-only and cannot be updated or deleted.
  • Idempotency: Clients supply an idempotency key with write requests. Retrying a request with the same key must return the original transaction result without creating duplicate postings or side-effects.
  • Account Balances with Freshness Guarantees: Support querying an account balance with explicit freshness tags (e.g., strongly consistent real-time balance vs. snapshot/eventually consistent balance as of a given timestamp or checkpoint).
  • Corrections & Reversals: System must handle reversals through explicit compensating entries rather than modifications to past records.

Non-Functional Requirements

  • Durability & Correctness: Zero tolerance for data loss or ledger imbalances. Transactions must satisfy ACID properties.
  • Availability & Latency: 99.999% write availability with p99 write latency under 100ms.
  • Hot Account Scalability: Prevent lock starvation on system-wide accounts (e.g., platform fee collection) that participate in a large fraction of all transactions.

Scale Assumptions

  • Accounts: 100 million total accounts.
  • Throughput: 10,000 transactions/second (TPS) average, peaking at 50,000 TPS.
  • Postings per Transaction: 2 to 4 postings on average.
  • Hot Accounts: Top 0.01% of accounts experience up to 5,000 postings/second.
  • Retention: Immutable records must be queryable online for at least 7 years.

What to Cover

  1. API & Data Model: Define the core primitives (Ledger, Account, Transaction, Posting) and the API contract for recording transactions and reading balances.
  2. Idempotency & Concurrency: Detail how concurrent requests with identical or conflicting idempotency keys are handled at the storage layer.
  3. Scaling & Sharding: Explain your partitioning strategy, addressing cross-shard transactions and hot account contention.
  4. Balance Materialization & Freshness: How balances are calculated (e.g., aggregate rollups, snapshots) and how freshness guarantees are fulfilled.
  5. Reconciliation & Auditing: Mechanisms to detect discrepancies and verify integrity across the ledger.

Hints

Hint 1

Separate the append-only ledger log of postings from the read-optimized materialized balance views to prevent write-lock contention.

Hint 2

To handle hot accounts, consider virtual sub-accounts or sharded counter techniques to distribute writes across distinct partitions before aggregating.

Hint 3

Enforce idempotency at the database engine level using unique constraints on the idempotency key and account identifier within the same atomic transaction that writes the postings.

Follow-up questions

  • How do you handle distributed atomicity when a transaction's postings span accounts located on different database shards?
  • If a network partition causes a client timeout while posting a transaction, how does the client recover and safely determine the transaction state?
  • How would you design the asynchronous reconciliation worker to continuously verify that every transaction balances to zero and detect any data tampering?