The Question
Design

Cinema Ticket Booking System Design

Design a high-scale cinema ticket booking platform like Fandango or BookMyShow. The system must support searching for movies by location, viewing real-time seat availability, and reserving seats for a limited window (e.g., 10 minutes) during checkout. Focus on handling extreme traffic spikes for blockbuster releases where thousands of users may attempt to book the same seats simultaneously. Address data consistency, high availability, and the management of temporary seat holds.
PostgreSQL
Redis
Elasticsearch
Kafka
gRPC
CDN
JWT
Microservices
Questions & Insights

Clarifying Questions

Scale & Traffic: What is the expected scale (DAU and peak QPS)? Assumption: 10M DAU, with peaks of 50,000 QPS during major movie releases.
Geographic Scope: Is this global or regional? Assumption: Global platform, but seat booking is cinema-specific.
Concurrency: How long should a seat be held during the checkout process? Assumption: 10 minutes.
Inventory Complexity: Are there different ticket types (VIP, Child) and dynamic pricing? Assumption: Support for various ticket types and static pricing per showtime for MVP.
Payment: Do we handle payments or use a third-party provider? Assumption: Third-party integration (Stripe/PayPal).

Thinking Process

Core Bottleneck: High contention on specific showtime seat maps during "Blockbuster" releases.
Logical Progression:
How do we ensure no two users book the same seat (Double Booking)?
How do we handle high-volume read traffic for movie listings and seat availability?
How do we manage the temporary "Hold" state for seats and handle timeouts?
How do we ensure the system remains available if the payment provider or notification service lags?

Bonus Points

Transactional Outbox Pattern: Used to ensure that seat status updates and downstream events (like sending a ticket via email) happen atomically.
Optimistic Concurrency Control (OCC): Implementing version checks in the database to handle high-concurrency seat selection without heavy row locks until the final step.
Database Sharding Strategy: Sharding the Bookings and Seats tables by ShowtimeID to localize write contention and scale horizontally.
Idempotency Keys: Strict enforcement of idempotency for payment processing and booking creation to prevent duplicate charges.
Design Breakdown

Functional Requirements

Core Use Cases:
Users can search/browse movies by city and date.
Users can view real-time seat availability for a specific showtime.
Users can select seats and hold them for 10 minutes.
Users can complete payment and receive a digital ticket.
Scope Control:
In-scope: Search, Seat Selection, Booking Management, Payment Integration.
Out-of-scope: Popcorn/Food ordering, Cinema hardware integration, User reviews/social features.

Non-Functional Requirements

Scale: Support 100,000+ concurrent users and 50k QPS peak write load.
Latency: Search results in <100ms; Seat selection response in <50ms.
Availability & Reliability: 99.99% availability (Highly available during peak sales).
Consistency: Strong Consistency for seat reservations (No double booking). Eventual Consistency for movie catalog and search.
Fault Tolerance: Graceful degradation if the search index is stale; robust retry logic for payment callbacks.

Estimation

Traffic: 10M DAU. Assuming 5% book a ticket = 500k bookings/day. Peak traffic (Blockbuster) = 10x average. Peak QPS ≈ 50k.
Storage: 500k bookings/day * 1KB per record = 500MB/day. ~180GB/year. Movie/Cinema metadata is negligible (<10GB).
Bandwidth: 50k QPS * 2KB response = 100MB/s (Egress).

Blueprint

Concise Summary: A microservices architecture leveraging a relational database with strict ACID properties for seat inventory and a search engine for high-performance browsing.
Major Components:
API Gateway: Entry point for rate limiting, auth, and request routing.
Search Service: Uses Elasticsearch to handle high-volume, faceted movie searches.
Booking Service: Manages the state machine of a booking (Created -> Reserved -> Paid/Expired).
Inventory/Seat Service: Handles the high-contention logic of seat locking.
Payment Service: Interfaces with 3rd party providers and manages idempotency.
Simplicity Audit: This design avoids complex distributed transactions across multiple databases by centralizing the "Seat Status" in a single transactional store per shard.
Architecture Decision Rationale:
Why this architecture?: Separating Search from Booking ensures that heavy browsing traffic doesn't starve the resources needed for critical booking transactions.
Functional Satisfaction: Meets all user flows from discovery to payment.
Non-functional Satisfaction: Scalable via sharding, reliable via asynchronous messaging for side effects, and consistent via RDBMS transactions.

High Level Architecture

Sub-system Deep Dive

Edge (Optional)

Content Delivery: Use CDN for movie posters, trailers, and static UI assets.
API Gateway: Implements JWT validation and Global Rate Limiting (preventing bot scraping of seat maps).
Load Balancing: L7 Load Balancer with session affinity (optional) but primarily round-robin to stateless service pods.

Service

Booking Service (State Machine):
Statuses: PENDING, RESERVED, CONFIRMED, CANCELLED, EXPIRED.
Handles "Cleanup" of expired RESERVED tickets via a TTL-based worker or Redis expiration events.
API Schema:
POST /v1/bookings/reserve: Request { showtime_id, seat_ids[] } -> Response { booking_id, expires_at }.
Protocol: gRPC for internal service communication; REST for external.
Resilience:
Circuit breakers on Payment Provider calls.
Exponential backoff for seat-locking retries.

Storage

Access Pattern: Heavy read for search; High-concurrency write/update for seats.
Database Table Design (Seat Inventory):
showtime_seats: showtime_id (PK/Shard Key), seat_id (PK), status (Available/Reserved/Occupied), version (for OCC), booking_id (FK), reserved_until (Timestamp).
Technical Selection: PostgreSQL for Seat Inventory due to ACID compliance and row-level locking. Elasticsearch for Movie Search.
Distribution Logic: Sharding showtime_seats by showtime_id. This ensures all seats for a specific movie screening are on the same physical database node, allowing for local ACID transactions.

Cache

Purpose:
Caching frequently accessed Movie/Cinema metadata.
Distributed Locking for seat selection to reduce DB load during the "First-come-first-served" rush.
Key-Value Schema: lock:showtime_id:seat_id -> user_id (TTL 10m).
Technical Selection: Redis. High throughput and built-in TTL features are ideal for short-lived seat holds.

Messaging

Purpose: Decoupling the critical booking path from side effects like email/SMS notifications and updating the Search Index with seat availability counts.
Event Schema: BookingConfirmedEvent { booking_id, user_id, seat_details, price }.
Technical Selection: Kafka. Provides durability and allows multiple consumers (Analytics, Email, Search Update) to process the same event.

Infrastructure (Optional)

Observability: Prometheus for metrics (booking success rate), ELK stack for logs.
Security: All PII (emails, names) encrypted at rest in the Booking DB.
Wrap Up

Advanced Topics

Trade-offs: We chose Pessimistic Locking (or strict OCC) in the database for seat selection. While this limits extreme throughput compared to a NoSQL "Eventually Consistent" approach, it is a non-negotiable requirement to avoid double-booking.
Reliability: If the Redis cache fails, the system falls back to the RDBMS as the source of truth for seat status.
Bottleneck Analysis: The showtime_seats table is the hottest spot. Optimization involves using a memory-optimized table or "In-memory" RDBMS features for the current day's active showtimes.
Optimization: "Pre-rendering" seat maps as static JSON files in S3/CDN for popular movies, updated periodically, to reduce the load of 50k users fetching the same layout simultaneously.