System Design Interview: Design Ticket Booking System (BookMyShow, Paytm, District)
An online ticket booking service (such as BookMyShow, Paytm, or District) allows users to search, view metadata, and securely book seats for movies, live concerts, and public events at scale. This architectural blueprint walks through a rigorous, end-to-end High-Level Design (HLD) and Low-Level Design (LLD) interview breakdown for handling millions of concurrent users.
1. Step 1: Requirement Gathering (Functional & Non-Functional)
System design interviews are open-ended; the first step is to clarify both functional and non-functional requirements with your interviewer.
Functional Requirements
- Search Events: Users must be able to search for movies, concerts, or events based on keywords, geographic locations, and dates.
- View Event Details: Users must be able to inspect event metadata (directors, cast, descriptions, posters) and view real-time seat availability layouts.
- Book Tickets: Users must be able to reserve seats, execute secure payments, and receive definitive booking confirmation.
Non-Functional Requirements & Scale
- Scale / Daily Active Users (DAU): Designed to support a massive scale of 100 million Daily Active Users (DAU), generating heavy read traffic and intermittent write spikes during high-demand sales.
- Read vs. Write Asymmetry: Read requests (searching and viewing events) vastly outnumber write requests (confirming bookings and payments).
- CAP Theorem Application:
- Search & Viewing: Must prioritize Availability (A) and partition tolerance, ensuring users can always browse movies without latency or downtime.
- Booking & Seat Reservation: Must prioritize Consistency (C) and partition tolerance, guaranteeing absolute correctness so that no two users ever successfully book the exact same seat.
2. Core Entities Identification
Based on the functional workflows, the system manages four foundational domain entities:
3. API Design & REST Endpoints
APIs directly map to the core functional requirements. All responses handle pagination where datasets are large.
1. Search Events API
- Endpoint:
GET /api/v1/events/search - Query Parameters:
q(free text),location(lat/long or city string),date(YYYY-MM-DD),page,limit - Response: List of matching event summaries (Event IDs, titles, thumbnails, short descriptions).
2. View Event Details & Seats API
- Endpoint:
GET /api/v1/events/{eventId} - Response: Complete event metadata, venue details, and real-time seat map array with status (
available,reserved,booked).
3. Reserve Seats (Booking Step 1) API
- Endpoint:
POST /api/v1/bookings/reserve - Request Header:
X-User-Id(authenticated secure user context) - Request Body:
JSON
{ "eventId": "evt_987654", "seatIds": ["L12", "L13"] } - Response:
bookingId, expiration timestamp (TTL).
4. Confirm Payment & Booking (Booking Step 2) API
- Endpoint:
POST /api/v1/bookings/confirm - Request Body:
JSON
{ "bookingId": "bk_123456", "paymentDetails": { "gatewayToken": "tok_visa_debit_xyz", "amount": 45.00 } } - Response: Confirmation status, receipt, and ticket QR code bundle.
4. High-Level Design (HLD): Microservices Architecture
To handle 100 million DAU, a monolithic server is unviable because it cannot scale horizontally under sudden spikes. We break the system down into decoupled microservices fronted by an API Gateway.
5. Low-Level Design (LLD): Database Architecture & Polyglot Persistence
Different services have radically different access patterns, necessitating a polyglot persistence strategy.
6. Real-Time Search & Ingestion Pipeline (CDC)
Because Apache Cassandra is optimized for writes rather than flexible ad-hoc searches across titles, dates, and locations, we leverage ElasticSearch for search queries.
The Ingestion & Synchronization Flow
- Metadata Mutation: Event operators update movie or concert details, writing changes to Cassandra.
- Change Data Capture (CDC): A Debezium connector taps into Cassandra mutation logs.
- Event Streaming: Debezium pushes data change events into an Apache Kafka topic.
- ElasticSearch Ingestion: A background ingestion consumer reads from Kafka and indexes the documents into ElasticSearch in near real-time.
7. Low-Level Design (LLD): Concurrency & Distributed Booking Engine
Preventing double-booking when thousands of users attempt to grab the exact same seat simultaneously is the most critical challenge in ticket booking systems.
Naive vs. Production-Grade Approaches
- Naive Approach (Cron-Based Expiry): Storing reservations directly in a relational database with a 10-minute expiration flag, requiring a periodic cron job every minute to scan and reset expired reservations.
- Flaws: Extremely heavy database scan overhead, poor real-time responsiveness, race conditions, and lack of reliability.
- Production Approach (Redis Distributed Locks & TTL): Utilizing Redis in-memory atomic operations and automatic TTL expiration.
The Step-by-Step Distributed Booking Workflow
8. Handling Traffic Surges & Flash Sales (Waiting Queues)
When hosting extremely high-demand events (e.g., international concerts like Coldplay), millions of users hit the platform concurrently, threatening to overwhelm the backend booking microservices.
The Waiting Queue Architecture
To protect internal services from crashing during flash sales, we introduce an asynchronous queuing buffer:
- Virtual Waiting Rooms: Users are assigned a queue position and token.
- Controlled Throttling: Kafka releases users into the active booking pool at a rate the database and payment gateway can safely handle, ensuring 100% system stability under peak loads.
9. Summary and Key Takeaways
- Functional Scoping: Focus on three core pillars: searching events, viewing rich metadata with seat maps, and executing two-step reservations and payments.
- Non-Functional Balance: Apply CAP Theorem strategically—prioritize Availability for browsing and search, and Consistency for seat reservations and payments.
- Polyglot Persistence: Combine Cassandra for highly available event metadata, ElasticSearch for sub-second multi-attribute search, MySQL/Postgres for financial transactions, and Redis for ephemeral locks.
- Change Data Capture (CDC): Keep search indexes synchronized with primary databases in near real-time using Debezium and Kafka.
- Atomic Concurrency Control: Avoid clunky cron jobs by using Redis TTL keys for ephemeral seat locking during the 10-minute payment window.
- Traffic Shielding: Protect backend infrastructure during high-hype flash sales by deploying Kafka-backed virtual waiting rooms.