Skip to content
QuizMaker logoQuizMaker
Activity
System Design: The Complete Guide
3. Advanced Case Studies
1. Introduction to System Design
2. Vertical vs Horizontal Scaling
3. Load Balancing
4. Caching Strategies
5. CDNs (Content Delivery Networks)
6. SQL vs NoSQL
7. Database Sharding & Partitioning
8. The CAP Theorem
9. Microservices Architecture
10. Message Queues & Event Streaming
12. Design BookMyShow (Ticket Booking)
14. Design Dropbox (Cloud File Storage)
15. How to Approach Any System Design Interview
16. Back-of-the-Envelope Estimation
17. Consistent Hashing
18. Bloom Filters & Probabilistic Data Structures
19. Database Replication
20. Leader Election & Consensus (Raft & Paxos)
21. Distributed Transactions (Saga, 2PC, Outbox)
22. Event Sourcing & CQRS
23. Unique ID Generation at Scale
24. Rate Limiting Algorithms
25. Circuit Breakers & Bulkhead Pattern
26. API Gateway, Proxies & Service Mesh
27. Real-Time Communication
28. Observability (Tracing, Logging, SLOs)
30. Design a Chat System (WhatsApp)
31. Design YouTube (Video Streaming)
32. Design a Web Crawler
CONTENTS

12. Design BookMyShow (Ticket Booking)

Design a high-concurrency seat-reservation system with strong correctness guarantees.

Feb 22, 20268 views0 likes0 fires
18px

The Core Challenge

Ticketing systems are the ultimate interview question because they combine every hard problem in distributed systems:

  • High read traffic (browsing shows and seat maps).
  • Spiky write traffic (new releases and flash sales).
  • Hard correctness (if two users both see "Seat A10 available" and click "Book," only one can win).
  • Distributed payments (partial failures everywhere—timeouts, retries, double charges).

Real-World Scale: The Taylor Swift Problem

When Taylor Swift''s Eras Tour went on sale through Ticketmaster, over 14 million users hit the site simultaneously—more traffic than the entire Super Bowl website gets in a year. The system buckled, crashed, and became a national news story. This is the exact problem you''re solving: how do you handle millions of concurrent users competing for a finite number of seats without overselling, crashing, or losing payments?

BookMyShow in India faces similar spikes when blockbuster Bollywood movies or cricket matches go on sale—handling 5-10 million requests per minute during peak releases.

Requirements

Functional

  • Browse movies/events by city and date.
  • View showtimes and seat maps for a specific show.
  • Select seats and temporarily reserve ("hold") them.
  • Pay and confirm the booking.
  • Cancel/refund based on policies.

Non-Functional

  • Correctness over availability for seat inventory—it''s better to show "sold out" than to oversell and cancel tickets later.
  • Low-latency browsing—cache browse data aggressively.
  • High concurrency for seat selection during flash sales.
  • Resilient payment handling across gateway failures and retries.

Capacity Estimation

  • Peak browsing: 200K RPS (mostly cacheable queries).
  • Peak seat holds during flash sales: 20K RPS.
  • Peak confirmed bookings: 5K RPS (payment-gated writes).

API Design

GET /api/v1/cities/{cityId}/shows?date=2026-02-22

GET /api/v1/shows/{showId}/seatmap

POST /api/v1/shows/{showId}/holds
{ "seatIds": ["A10","A11"], "userId": "..." }
→ { "holdId": "...", "expiresAt": "..." }

POST /api/v1/holds/{holdId}/confirm
{ "paymentIntentId": "..." }
→ { "bookingId": "..." }

Data Model

shows                    show_seats
-----                    ----------
show_id (PK)             show_id + seat_id (PK)
venue_id                 status (AVAILABLE | HELD | BOOKED)
movie_id                 hold_id (nullable)
start_time               hold_expires_at (nullable)

holds                    bookings
-----                    --------
hold_id (PK)             booking_id (PK)
show_id                  show_id
user_id                  user_id
status (ACTIVE|EXPIRED|  seat_ids (array/json)
        CONFIRMED)       status (CONFIRMED|CANCELLED)
expires_at               created_at

Architecture

Clients → CDN (static assets) → API Gateway (auth, rate limits)
  ├── Show Catalog Service  → Cache (Redis) → Read DB
  ├── Seat Inventory Service → Inventory DB (strong consistency)  
  ├── Booking Service (saga orchestrator) → Event Queue
  ├── Payment Service (gateway integration)
  └── Notification Service (email/SMS confirmation)

The Virtual Waiting Room (Handling Flash Sales)

During high-demand events, don''t let all users hit the seat selection page at once. Instead, implement a virtual queue:

  1. Users enter a waiting room and receive a queue position.
  2. Batches of users (e.g., 1,000 at a time) are admitted to the seat selection page.
  3. Each admitted user has a time-limited session (e.g., 10 minutes) to select and pay.

Ticketmaster''s "Smart Queue" and BookMyShow both use this pattern now. It prevents thundering herd problems and gives admitted users a fair, responsive experience rather than everyone getting a slow, crashing page.

Preventing Double Booking (The Critical Piece)

The key is making seat state changes atomic. Two users clicking "Book Seat A10" at the same millisecond must not both succeed.

Correct Approach: Conditional Update in a Transaction

UPDATE show_seats
SET status = ''HELD'',
    hold_id = :holdId,
    hold_expires_at = now() + interval ''5 minutes''
WHERE show_id = :showId
  AND seat_id IN (:seatIds)
  AND status = ''AVAILABLE''
RETURNING seat_id;

If the returned seat count doesn''t match the requested count, rollback everything and tell the user "some seats are no longer available." This atomic check-and-set pattern is the gold standard.

Why Not "Lock in Redis Only"?

Redis locks are useful for performance optimization, but the source of truth must be durable. If Redis restarts and your "locks" disappear, you could oversell seats. Use Redis as a fast-fail check ("is this seat likely available?") but always confirm and commit in the database.

Hold Expiration

Holds must expire automatically (typically 5-10 minutes) to prevent seat hoarding:

  • DB-based sweeper: A periodic job finds expired holds and releases seats back to AVAILABLE.
  • Event-driven: Schedule a delayed message ("release hold XYZ") when the hold is created.
  • Hybrid (recommended): Delayed message for timely release + periodic sweeper as a safety net for missed messages.

Booking Confirmation (Saga Pattern)

  1. Create hold (seats → HELD).
  2. Create payment intent with the payment gateway (Stripe, Razorpay).
  3. On payment success: Mark hold CONFIRMED, seats → BOOKED, create booking record, send confirmation.
  4. On payment failure/timeout: Let hold expire naturally, seats return to AVAILABLE.

Idempotency is critical: Payment gateways retry webhooks. Your confirm endpoint must handle receiving the same webhook multiple times without creating duplicate bookings or charging twice. Use the paymentIntentId as an idempotency key.

Caching Strategy

  • Cache browse data (movies, venues, showtimes) aggressively—this changes infrequently.
  • Do NOT heavily cache seat availability. It changes constantly during sales. If you cache it, keep TTL under 2 seconds and always re-verify on hold creation.
  • Use Redis for session management and rate limiting during flash sales.

Failure Modes and Graceful Degradation

  • Payment callback delayed: Use webhook + polling + timeouts. Don''t release seats until you''re certain payment failed.
  • Inventory DB overloaded: Protect with rate limits and fast-fail. Browsing should remain healthy even when booking is degraded.
  • Partial outages: Allow users to browse shows and view seat maps even when the booking system is temporarily degraded ("degraded mode").

[!IMPORTANT] Interview tip: The ticket booking system is fundamentally about optimistic concurrency control with the conditional UPDATE pattern. Always explain why the database (not Redis alone) must be the source of truth for seat state, and always mention hold expiration with a sweeper as a safety net.

Share this article

Share on TwitterShare on LinkedInShare on FacebookShare on WhatsAppShare on Email

Test your knowledge

Take a quick quiz based on this chapter.

hardSystem Design
Quiz: Ticket Booking
5 questions6 min

Continue Learning

14. Design Dropbox (Cloud File Storage)

Advanced
7 min

15. How to Approach Any System Design Interview

Beginner
18 min

16. Back-of-the-Envelope Estimation

Beginner
14 min
Lesson 1 of 2 in 3. Advanced Case Studies
Next in 3. Advanced Case Studies
14. Design Dropbox (Cloud File Storage)
← Back to System Design: The Complete Guide
Back to System Design: The Complete GuideAll Categories