Diagrammatic

Design Backend for an App to Distribute 6 Million Free Burgers in One Hour — System Design Interview Practice

Design a system to handle flash distribution of limited items with high concurrency and fairness. Work through the requirements, architecture trade-offs, and an interactive design review.

Concepts and architecture decisions to consider

  • flash saleConcept to explore
  • concurrencyConcept to explore
  • high trafficConcept to explore
  • inventoryConcept to explore
  • scalabilityConcept to explore

Interview prompt

Design a fair, abuse-resistant flash-distribution system that gives away six million vouchers or burgers in one hour while keeping inventory, eligibility, and redemption correct under extreme concurrency.

  • Define eligibility, fairness, admission, reservation, redemption, expiry, and inventory ledgers with an idempotency key per user/campaign.
  • Absorb millions of arrivals with waiting-room admission, bot defenses, quotas, randomized or timestamped ordering, and bounded queues.
  • Keep the hot path small and asynchronous; make inventory allocation atomic and reconcile abandoned reservations and store redemptions durably.
  • Explain regional capacity, retries, fraud, queue failure, campaign pause/resume, observability, and a transparent sold-out mode.

Requirements and scale assumptions

  • Admit eligible users, issue a fair position/token, reserve an item, confirm redemption, and expose queue and reservation status.
  • Enforce one-per-user/device limits, campaign windows, inventory variants, expiration, cancellation, and store/fulfillment handoff.
  • Make retries safe, prevent oversell and double redemption, audit decisions, and recover from queue, payment-free fulfillment, or region failures.
  • Absorb at least 10 million arrival attempts in an hour while keeping allocation correctness and a bounded admission response.
  • Distribute six million successful allocations without a single hot key or unbounded synchronous work.
  • Do not lose committed state; make retries and duplicate events safe.
  • Degrade safely when downstream workers, caches, or external dependencies fail.
  • 10M arrivals/hour and 6M available items across thousands of stores
  • Partition by the primary tenant, user, item, or geographic key and isolate hot partitions.
  • Keep serving state bounded; retain raw events or durable records for replay and auditing.
  • Peak scale: 10M arrivals/hour; 6M inventory — Capacity assumption that drives partitioning and backpressure.
  • Latency target: admission absorbs 10M/hour; no oversell — User-facing budget for the primary request or read path.
  • Durable boundary: Committed before async — The campaign inventory and redemption ledger are authoritative; queue positions and counters are derived state.
  • Async boundary: At-least-once workers — Keep Queue-based request handling, Redis for atomic inventory decrements, Rate limiting per user off the synchronous path.

Key entities

  • RedemptionIntentintentId, customerId, offerId, status, version, idempotencyKey

    Idempotent backend reservation intent with an explicit lifecycle.

  • InventoryClaimclaimId, itemId, quantity, expiresAt, status, version

    Short-lived conditional claim that protects scarce availability.

  • PaymentAttemptattemptId, intentId, provider, requestHash, status, providerRef

    Retry-safe payment attempt with unknown-outcome reconciliation.

  • FulfillmentStateintentId, stage, owner, lastEventId, status, updatedAt

    Durable downstream reservation fulfillment progress.

Data flow

  1. 1. Search and price current candidatesThe backend query path combines catalog, eligibility, price, and current availability without treating a stale index as a final claim.
  2. 2. Claim scarce inventoryThe backend service creates a short-lived conditional claim keyed by item and request idempotency before charging or confirming.
  3. 3. Confirm the redemption safelyPayment, policy, and inventory transitions are versioned; unknown provider outcomes are reconciled before retry.
  4. 4. Publish fulfillment workThe committed backend intent emits an event for partner, packing, delivery, or campaign dispatch workers.
  5. 5. Expire, cancel, and reconcileExpiry and cancellation release claims idempotently while reconciliation compares internal state with external providers or partners.

Deep dives and trade-offs

  • Inventory claims and oversell controlUse conditional writes or a serialized inventory partition for backend scarce capacity. Give holds an expiry and reaper, but never release a confirmed claim from a stale worker. Separate searchable availability from the authoritative claim path.
  • Payment and unknown outcomesBind backend payment attempts to the intent and request hash, not just the customer session. Treat timeout as unknown, query or reconcile provider state, and avoid a blind second charge. Keep sensitive payment tokens outside business records and logs.
  • Fulfillment and partner recoveryPublish backend events after commit, consume at least once, and track per-stage progress. Use reconciliation against partner feeds or delivery evidence instead of assuming a callback arrives. Expose pending and expired status so the client can explain what happened.
  • Reservation versus oversell tolerancePrefer a short-lived backend claim for scarce inventory and state the consistency scope explicitly. A cache or search index cannot safely decrement the final room count.
  • Synchronous checkout versus asynchronous fulfillmentCommit the reservation intent synchronously and move partner or delivery work behind events. Waiting for downstream fulfillment makes retries ambiguous and increases checkout tail latency.
  • Precompute availability versus compute at read timePrecompute common search dimensions but validate the final claim against authoritative state. Serving only a precomputed backend availability view creates oversell or stale-price failures.
Diagrammatic — system design practice and architecture review.