> For the complete documentation index, see [llms.txt](https://avinandanbanerjee99.gitbook.io/system-design-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://avinandanbanerjee99.gitbook.io/system-design-notes/examples/ticket-booking-system.md).

# Ticket Booking System

### Feature Expectations

#### Fuctional/Business Requirements

* List cities where the cinema halls are
* Show movies in that city
  * (***Optional)*** Show recommendations to user based on their profile
* Show halls in that city with a movie with show times
  * (***Optional)*** Prioritize halls by proximity to user's location
* Let users book tickets at a specified location in a hall at a show time
  * Show seating arrangement. Let multiple tickets be booked
* Tickets should be put on hold for 5min till payment is confirmed
* ***(Optional)*** Users should be waitlisted, if their desired ticket is on hold
* ***(Optional)*** Search for a movie based on parameters
* (***Optional)*** Comment/Review feature for movies on user facing application
* Deliver ticket booking details (eg. QR code, ticket invoice) to the user

#### Non Functional Requirements

* Highly concurrent system - handle bookings fairly via FCFS!
* ***(Optional)*** Protect against mass booking of tickets (fraud, government mandate)
* High availability
  * ***(Optional)*** How many 9s?
* Strongly consistent bookings
  * Users do not book and pay for same ticket multiple times
* Do not handle partial bookings of multiple tickets - they are atomic
* Between consistency and availlability -
  * Consult product team -
  * In my opinion - it is worse for users to see wrong/old bookings, rather than not see a booking at all

### Estimations

#### Throughput

* Number of page views a day - 5 million
* Number of bookings (each seat) a day
  * 500 cities \* 30 theaters \* 5 halls \* 150 tickets
  * \~ 0.1 M, lets assume all tickets are booked
* Numbers for peak workloads
  * Let's assume half bookings - 0.05M happen in 1 hr
  * \~ 2K bookings in an hour at peak - this is manageable!

#### Storage

* Assumption - each row is \~50 bytes
* 5 year storage estimate (for bookings) -
  * 0.1M \* 30 \* 12 \* 5 \* 50KB
  * 9 TB
* However - inactive bookings to be archived - storage will mostly be in data warehouse!

### **API Design**

* TBD

### Data Model

* TBD

### High Level Design

* Client is served by geographically closest CDN
  * Serves static HTML - generated every \~1min by servers and sent to CDN
* Client communicates with application servers via load balancers
* Application servers talk to -
  * Cinema (City/Hall) services
    * These are backed by ElasticSearch - fuzzy search and supports misspellings, close words etc.
  * Booking service - MySQL (Includes available tickets, reserved tickets)
  * User detail service - SQL database
* SQL Databases have master-slave replication to horizontaly scale
* Older data (especially bookings) in SQL stores is sent to an archival store - eg. S3 via Archival service
* Redis cache is useful in front of Cinema and User Detail service
  * Booking service frequently changes - not useful here
  * Write-through cache invalidation strategy
* Booking service talks to
  * Payment service - interface for a payment gateway like Stripe
  * Reservation service - handles reserving for 5min, sending users to queue
* Booking service feeds
  * to Ticket Generation service asynchronously (Kafka)
  * Analytics service asynchronously
* Ticket generation service async sends
  * details (QR) to user's email
* Analytics service stores data in Redshift/Snowflake for product team
* ***(Optional)*** Recommendation service stores data in Hadoop
  * Spark generates recommendations based on user profile category stored beforehand
  * These recommendations are stored in SQL database and served to app server on landing screen API calls
* ***(Optional)*** NoSQL database such as DynamoDB handles comments/reviews for every movie

### Deep Dive

#### Perform a Booking

* Three states - unreserved, reserved, sold - speak about transitions

#### Handling concurrent bookings

* Have two tables -
  * one for bookings (with a col as booking UUID)
  * one for available tickets (with seat details etc.)
  * a new booking is made and a seat row is deleted as part of a transaction
  * in case seat is booked - then deletion will fail - hence transaction fails - booking row never created
* Basically rely on Transaction Isolation Levels?

#### Handling waiting users

#### Handling reservation expiry

* TTL feature of Redis
  * Insert a key into Redis - it sends a callback after TTL
  * Use that callback to cancel reservation
* Alt - Implement a polling mechanism to not rely on callbacks

#### Handling distributed transactions

### Identify Bottlenecks

Single points of failure -

* Master-slave replication

Geographically distinct user base

* Partition the data stores
  * Good idea to partition based on showID rather than movie ID - more equally distributed across servers as some movies are "hotspots"
* Partition the services (bulk ahead pattern)
* Use multiple regions
