Skip to main content

Design E-Commerce Inventory / Flash Sale (Ticketmaster)

Level 10: Level 10: Applied Case Studieshard40 minflash-saleinventorycontention

Prevent oversell with a single atomic conditional decrement (never read-then-write), use reservation holds with TTL and automatic release for the cart window, and put a fair, rate-limiting waiting room in front to shed and pace the spike so the inventory store sees bounded load.

Correctness and concurrency collide

A flash sale is the interview where correctness and concurrency collide. You have a finite inventory (10,000 concert seats), millions of buyers arriving in the same second, and one absolute rule: never oversell. Everything else (fairness, UX, latency) is negotiable, but selling seat 4A twice is a lawsuit.

The read-modify-write race

If two requests both read available = 1, both decide "yes, buy," and both write available = 0, you have sold one item twice. Naive application-level checks always lose under concurrency. You need the decrement to be atomic. Three real options: (1) an atomic conditional update in the database, UPDATE inventory SET available = available - 1 WHERE item_id = ? AND available > 0, and check that exactly one row changed; (2) an atomic operation in Redis (DECR with a Lua script that rejects going below zero), serving as a fast front-line counter backed by durable storage; (3) a per-item serialized queue where a single consumer processes purchase requests for a hot item in order, converting contention into a sequential log.

Interview nuance: interviewers deliberately probe the race. State plainly that you never do "read available, then write" in app code; the check and decrement must be a single atomic operation, and you verify the affected-row count to confirm you actually won the decrement.

Reservation holds

Real commerce does not charge instantly, so you need reservation holds. When a buyer adds a seat to their cart, you decrement inventory and create a hold with a TTL (say 10 minutes). The seat is unavailable to others during the hold. If the buyer completes checkout, the hold converts to a sale; if the TTL expires, a background sweeper (or a lazy check on next read) releases the seat back to inventory via an atomic increment. This prevents both oversell and permanent leakage from abandoned carts. Optimistic locking (version numbers, retry on conflict) works when contention is low; pessimistic locking or serialized queues are better for genuinely hot items where most optimistic attempts would fail and retry-storm.

The waiting room

You cannot let 5 million people hit checkout simultaneously; you would melt the inventory store no matter how atomic it is. Put a virtual waiting room in front: arriving users get a queue token, are shown a "you are number 480,000 in line" page, and are admitted in controlled batches at a rate the backend can absorb (say 5,000 checkouts/sec). This sheds and paces load and provides fairness (FIFO or a randomized lottery to defeat bots). Only admitted users can even attempt a reservation, so the inventory store sees bounded QPS regardless of how many people showed up.

5M arrivals -> Waiting Room (token, FIFO/lottery) -> admit 5K/sec
   -> Reservation (atomic decrement + hold TTL) -> Checkout saga -> Payment -> convert hold to sale
                                    \-- TTL expiry --> atomic increment (release) --/

Hot-item sharding has a limit: you cannot shard a single seat, so the truly contended item is serialized. Accept that a sold-out item's throughput is bounded by one atomic counter, and design the waiting room so most users never reach it.

Recap: prevent oversell with a single atomic conditional decrement (never read-then-write), use reservation holds with TTL and automatic release for the cart window, and put a fair, rate-limiting waiting room in front to shed and pace the spike so the inventory store sees bounded load.

Apply

Your turn

The task this lesson builds to.

Design ticket/seat purchasing that never oversells a finite inventory during a flash sale with millions of concurrent buyers.

Think about

  1. How do you prevent oversell under massive concurrency?
  2. How do reservation holds with timeouts work?
  3. How does a waiting room shed and fairly admit spike traffic?

Practice

Make it stick

A second problem on the same idea, so it survives past today.

Design the on-sale system for Taylor Swift tickets on Ticketmaster, where 14 million people queued for 2 million seats across dozens of venues, bots made up a large share of traffic, and the previous system melted down. Prioritize fairness, oversell-safety, and graceful degradation under 10x the expected load.

Think about

  1. Why does a randomized lottery beat pure FIFO against bots?
  2. How does adaptive admission tied to backend health prevent the meltdown?
  3. How do you shard inventory so hot events do not share a contention domain?