Skip to main content
HS
HiSETSuccess
LeetCode Prep

System Design

Comprehensive interview guide: scalability, databases, distributed systems, cloud architecture, and full case-study walkthroughs — plus adaptive quizzes.

Case study

Design Ticketmaster Event Booking

Sell concert tickets fairly under extreme flash-sale load without overselling or double-booking seats.

concurrencyinventoryqueue

Requirements

  • Functional: browse events; select seats; hold during checkout; purchase; e-ticket
  • Prevent double booking of same seat
  • Queue users during high-demand onsales (1M users, 10K seats)
  • Non-functional: hold TTL 10 min; purchase idempotent; 99.99% inventory accuracy
  • Scale: 50K concurrent checkout sessions during mega onsale

Back-of-envelope Estimation

MetricCalculationResult
Flash sale1M users, 10K seats100:1 oversubscription
Peak RPS1M enter queue in 1 min~17K/sec gate traffic
Seat hold writes50K concurrent × 4 seats avg200K held seats max
Inventory readsEvery seat map poll ~1/sec/userCDN + cache critical

API Design

EndpointDescription
GET /v1/events/{id}/seatsSeat map with availability (cached)
POST /v1/holds{ eventId, seatIds[] } → { holdId, expiresAt }
POST /v1/orders{ holdId, paymentToken, idempotencyKey } → order
GET /v1/queue/{eventId}/statusVirtual waiting room position

Data Model

EntityFields
seatsevent_id, seat_id, section, row, status(available|held|sold), version
holdshold_id, user_id, seat_ids[], expires_at, status
ordersorder_id, hold_id, payment_id, status, created_at
waiting_roomevent_id, user_id, queue_token, position — Redis

High-level Design

Flash sale flow
User ──► Waiting Room (token bucket admit N/sec)
              └──► Seat Map (CDN cached static layout + Redis availability overlay)
              └──► Hold Service ──► optimistic lock seat rows (version column)
              └──► Checkout ──► Payment ──► confirm seats SOLD (atomic)

Deep Dive: Seat Hold with Optimistic Locking

UPDATE seats SET status='held', version=version+1 WHERE seat_id IN (...) AND status='available' AND version=@expected. If row count < requested, rollback and return 409. Hold expires via TTL job releasing seats.

Why not pessimistic lock

SELECT FOR UPDATE on 10K rows serializes the sale. Optimistic concurrency with version column scales; retry on conflict for alternate seats.

Deep Dive: Virtual Waiting Room

  • Admit 500 users/sec from FIFO queue to prevent origin meltdown
  • Queue token in cookie; random shuffle prevents bot front-running
  • Bots: device fingerprint + proof-of-work challenge before queue entry
  • Grace period if user refreshes — token tied to session

Failure Modes & Monitoring

SLOTarget
Inventory accuracy100% — zero oversell
Hold expiry enforcement< 30 sec after TTL
Queue admit rateStable under configured cap

Reconciliation job compares sold seats vs payment records nightly. Alert on any seat with status=sold without matching order.