How the interviewer opens it
“Design the backend for an app that gives away 6 million free burgers in one hour. Millions of users rush to claim one at the same time, and no burger may be given away twice.”
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
- Inventory and campaign window
- Accounts and repeat requests
- Traffic scale
- Read:write mix
- Latency
- Consistency versus availability
- Durability
- Fairness and overload
- User-visible result
- Deployment 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
- Show the campaign and approximate availability
- Claim one burger per authenticated account during the campaign
- Never grant more than 6 million claims or grant the same account twice
- Retrieve a durable claim result after retries or lost responses
Usually out of scope
- Restaurant fulfillment and physical burger redemption
- Payments, delivery, and restaurant-specific stock
- Proving that different accounts belong to different real people
- Cancellations, claim expiry, and returning stock
What interviewers probe
- Atomic allocation and one claim per account
- The system must preserve both a global stock bound and a per-account uniqueness rule. Checking stock, decrementing it, and recording the winner separately creates gaps where concurrency or crashes can violate either rule.
- Turning a request stampede into bounded useful work
- The opening peak is hundreds of times the minimum useful allocation rate. Most requests cannot win, and retries or polling can consume more capacity than actual allocation.
- Durable success, ambiguous outcomes, and failover
- A timeout does not tell the user whether a burger was granted. A failover that loses a recorded grant can reintroduce stock and grant the same entitlement again, even if normal-path allocation was atomic.
Common mistakes
- Conflating incoming attempts with required successful-grant throughput and designing the database for the entire uncontrolled peak.
- Using a check-then-decrement flow or updating inventory and claims independently.
- Treating Redis atomicity as sufficient without discussing persistence, failover, and acknowledged claims.
- Adding inventory partitions without preserving total stock or providing a way to use stock left in other buckets.
- Handling retries only by request ID, allowing the same account to win again with another ID.
- Ignoring overload, retry storms, and the difference between admission and a durable reservation.
The bar by level
- Senior (L5/E5)
- Derives useful throughput separately from incoming traffic; designs bounded admission and short transactions; addresses inventory-row contention without losing stock conservation; handles response loss, bucket exhaustion, and durable database failover. Explains why asynchronous persistence cannot support the stated success promise without additional machinery.
- Staff (L6+/E6+)
- Makes the safety and liveness obligations explicit: no oversell, no duplicate account grants, no lost acknowledged wins, and enough useful throughput to finish within the window. Defines fleet-wide admission and recovery boundaries, challenges unnecessary distributed state, and explains how regional allocation or database partitioning changes uniqueness, stock ownership, and failure behavior.