🎟️ Design Ticket Booking (BookMyShow) — System Design Interview Guide

Medium · Transactions & Concurrency

Design a ticket booking system like BookMyShow or Ticketmaster where users can browse events, select seats, and purchase tickets with guaranteed no double-booking under high concurrency.

Open the interactive Ticket Booking (BookMyShow) design on PrepGrind → Drag load balancers, caches, databases, and queues onto a canvas, run a live traffic simulation to watch latency and bottlenecks under load, and follow the full interview walkthrough below — free, in your browser.

Functional requirements

Non-functional requirements & scale

Capacity estimation

Core challenge: seat selection under concurrent load. A venue has 10,000 seats. 100,000 users try to book simultaneously. Must ensure no double-booking. Seat hold: user selects seat → seat reserved for 5 min → if payment not completed, seat released. Distributed lock required.

Core entities

API design

High-level design

Seat selection: Redis distributed lock on seatId. Hold: mark seats as HELD in DB + Redis SET with 5-min TTL. On TTL expiry: release seats. Payment: Stripe/Razorpay → confirm booking → generate QR. High traffic: queue requests and process sequentially per show.

Deep dives

🔒 Seat Locking Strategy

Option A: Pessimistic DB lock — SELECT FOR UPDATE on seat rows. Serialized, slow, doesn't scale to 100K concurrent users. Option B: Redis SETNX — SET seatId:showId userId NX EX 300 (atomic, 5-min TTL). If returns nil, seat taken. Sub-millisecond. Multiple seats: Lua script for atomic multi-seat hold (all-or-none). Release: Redis key deletion or TTL expiry.

⏱️ Hold Expiry

Redis key TTL = 300s (5 min). On expiry: Redis keyspace notification → Booking Service receives event → mark seats as AVAILABLE in DB. Problem: Redis keyspace notifications have at-least-once delivery. Solution: also store expiresAt in DB. Background job scans for expired holds every 30s (belt and suspenders). On any seat status read, check expiresAt.

🌊 Handling Traffic Spikes

IPL ticket release: 10M users hit "Book" simultaneously. Strategies: (1) Queue requests in SQS — serialize per show, process FIFO. (2) Virtual waiting room: user gets queue position, auto-refresh. (3) Rate limiting at gateway per showId (max 1000 req/sec per show). (4) Pre-warm cache with seat availability before sale opens. Show users fair queue experience vs HTTP 500 errors.

🎫 QR Code Generation

After payment confirmed: generate booking record in DB. QR payload: bookingId + userId + showId + HMAC signature (prevents forgery). Encode as QR code image → store in S3. Send link via email/SMS. On venue scan: decode QR → verify HMAC → check booking status in DB → mark as used. Offline QR validation via cached booking list for each show.

Scaling considerations

What interviewers expect by level

Practice more system design case studies

PrepGrind runs entirely in your browser, free, no installation required. Loading the interactive playground…