Skip to content
System design course
Ch.4 · Designing real systems·concept ·8 min read

Designing Ticketmaster

Sell event tickets under extreme bursts — a virtual waiting room to tame the thundering herd, seat holds that prevent double-selling, and fairness.


The problem

Design Ticketmaster: sell tickets to events, including flash sales where millions hit “buy” the instant a hot show opens for a few thousand seats. It’s the booking problem (Airbnb/flights) taken to the extreme of contention — the distinctive challenge is the thundering herd: surviving a massive synchronized spike while never double-selling a seat and staying fair.

Step 1 — Requirements

Functional: browse events; view a seat map with live availability; select + hold seats; checkout/pay; issue tickets. (Reserved seating is the hard mode; general admission is just a counter.)

Non-functional: handle massive traffic spikes (10⁶ users for 10³ seats), strong consistency (never sell a seat twice — CP), fairness (first-come or lottery, not just whoever has the fastest connection/bot), low latency, available.

Step 2 — The thundering herd: a virtual waiting room

The defining technique. You cannot let millions hit the seat-selection/booking system at once — it would melt. Put a virtual waiting room (queue) in front:

  • When the sale opens, users enter a queue (often FIFO by arrival, sometimes a randomized lottery for fairness).
  • The system admits a controlled trickle from the queue into the actual buying flow at a rate the booking backend can handle.
  • Waiting users see “you are number N in line” (served from a lightweight, cacheable queue service — not the booking DB).

This converts a spike into a steady, manageable stream, protecting the core and making the sale survivable. It’s the single most important idea here.

Step 3 — Seat holds (no double-selling under contention)

Once admitted, a user selects seats and gets a temporary hold so two buyers can’t grab the same seat:

  • Each seat is a strongly-consistent resource with states: available → held → booked.
  • Selecting a seat atomically transitions it to held (with a TTL, e.g. 5–10 minutes) — the conditional-update / lease pattern. A held seat is hidden from others.
  • If the user pays → booked; if the hold expires → back to available.

Even under massive concurrency, the atomic hold + a unique constraint per seat guarantees no double-sell (Airbnb/e-commerce pattern, contention dialed up).

Step 4 — The booking flow

sale opens → waiting room (queue) → admit at controlled rate
→ seat map (live held/available) → select → HOLD (atomic, TTL)
→ checkout → pay → CONFIRM (held → booked) → issue tickets
   (hold expires / payment fails → release seats back to available)

Step 5 — Fairness and anti-abuse

  • Fairness — FIFO queue or randomized lottery; per-user ticket limits; entry tokens.
  • Anti-bot — CAPTCHAs, rate limits, device/identity checks (bots are the real adversary in ticket sales) so real fans aren’t beaten by scripts.

Step 6 — Architecture

users → waiting room / queue service (lightweight, cacheable) → admission control
admitted → seat service (seat states, atomic holds, CP) + seat map (live)
→ checkout → payment → confirm → ticketing

The queue service is decoupled and scales independently; the seat service is the strongly-consistent core that only ever sees the admitted trickle.

Trade-offs to raise

  • Virtual waiting room (protects core, adds a wait) vs letting everyone in (meltdown). Mandatory at flash-sale scale.
  • Strong consistency for seats (CP) over availability — never double-sell.
  • FIFO vs lottery fairness; hold TTL (long = good UX but seats locked, can stall the sale; short = more churn).
  • Optimistic vs pessimistic seat locking — under high contention, atomic state transitions / short pessimistic holds win.

The interview cue

“Front the sale with a virtual waiting room (queue) that admits a controlled trickle, turning the thundering herd into a steady stream; admitted users get atomic seat holds (TTL) so no seat is double-sold (CP, unique-per-seat); pay → confirm → ticket, release on expiry; fairness via FIFO/lottery + per-user limits and anti-bot.” Waiting room + atomic holds is the distinguishing answer; implementation next.