Katkat

Design a Merchant Ledger Service

StripeSoftware Engineer · Onsite

Last updated

This question tests your ability to design a distributed ledger system that ensures high transactional integrity, strict consistency for financial balances, and reliable idempotency in a high-concurrency environment.

Problem Statement

Design a scalable Ledger Service for a payment platform that tracks account balances and records every transaction. The service must ensure that money is neither created nor destroyed due to race conditions or system failures.

Functional Requirements

  1. create_account(user_id): Initialize a new account with zero balance.
  2. get_balance(user_id): Return the current ledger balance for a user.
  3. transfer(from_id, to_id, amount, idempotency_key): Move funds between two accounts. This must be atomic.

Non-Functional Requirements

  • Strict Consistency: Account balances must always be accurate; partial updates are not allowed.
  • Idempotency: Retrying a request with the same key must not process the transfer multiple times.
  • Auditability: Maintain an immutable log of all transactions for reconciliation.
  • Scale: Support 10,000+ concurrent transactions per second.

Design Deliverables

  • Define the database schema and storage strategy.
  • Explain how you handle distributed transactions (e.g., Sagas, 2PC, or optimistic locking).
  • Describe how you ensure the idempotency guarantee.
  • Discuss how you handle high-frequency accounts (hot shards) that receive constant updates.

Hints

Hint 1

Consider the difference between storing a 'current balance' field versus calculating it as a sum of all transactions.

Hint 2

Think about using a transaction log (append-only) as the single source of truth to ensure auditability and simplify failure recovery.

Hint 3

Use database-level constraints or application-side reservation patterns to handle concurrency when multiple transactions hit the same account simultaneously.

Follow-up questions

  • How would you handle a scenario where a transaction fails halfway through the transfer process?
  • If the ledger database becomes a bottleneck, what partitioning or sharding strategies would you implement?
  • How would you support a 'pending' state for transactions that need to be held for a period before final settlement?