You are designing a payments API. Peak volume is modest - a few thousand requests per second. What is the dominant architectural driver and what does it force into the design?
Show the full answer Hide the answer
What is being tested
Whether you can identify a driver that is not about scale. Most candidates reach for throughput because that is what system design interviews have trained them to do.
The reasoning
A few thousand requests per second is not an interesting throughput problem — a single well-configured relational database handles it. The driver is correctness under retry, and it comes from an unavoidable fact about the environment rather than from any stated requirement.
Networks time out. A client that sends "charge this card £200" and receives no response cannot distinguish between "the request never arrived" and "the request succeeded but the response was lost". The only safe behaviour available to that client is to retry. Therefore the server will receive duplicates, and each duplicate, naively handled, is a second real charge against a real person's money.
That single driver propagates outward into decisions that look unrelated:
- Idempotency keys as a first-class API concept. The client supplies a key; the server records it and the response before performing the side effect, so a replay returns the original result rather than repeating the action.
- Persist intent before acting. The request record must be durable before the charge is attempted, or a crash between acting and recording leaves an untracked side effect.
- At-least-once outbound delivery with consumer-side deduplication. Webhooks must be retried, so consumers must tolerate repeats — and the API must say so loudly, because a merchant who assumes exactly-once will ship a double-fulfilment bug.
- Reconciliation as a standing process. Not incident response. Something compares the ledger with the acquirer's settlement file every day and raises the differences.
- Ordering must not be assumed. A
charge.succeededand acharge.refundedcan arrive out of order; consumers need the object state, not just the event.
What a strong answer adds
The contrast case. An analytics ingest pipeline receives duplicates from exactly the same retry mechanism, and correctly spends nothing on preventing them, because a duplicated page-view is harmless. Same mechanism, different cost of being wrong, entirely different architecture.
The other strong move is to name the second driver: auditability. Money movement must be explicable after the fact, which favours an append-only record of what happened over a mutable row showing what is currently true.
Common weak answers
Designing for throughput that does not exist. Adding a queue in front of the charge without explaining how the client learns the outcome. Saying "we will use exactly-once delivery", which is not available across a network boundary and signals that the candidate has not thought about the failure model.