System requirements
Functional:
List functional requirements for the system (Ask interviewer if stuck)...
- User Registration and Authentication: This is crucial to ensure that users can securely create accounts, log in, and access the platform's features. It forms the foundation for personalized user experiences and data security.
- Movie Listings and Showtimes: Displaying accurate and up-to-date information about movies, showtimes, theaters, and ticket availability is essential for users to make informed decisions.
- Ticket Booking: Allowing users to easily select movie showtimes, choose seats, and complete transactions is one of the primary purposes of the platform. A smooth booking experience is key to user satisfaction
- Payment Gateway Integration: Seamless integration with a secure payment gateway is crucial for processing online transactions securely and efficiently.
- Movie Listings and Showtimes: Displaying accurate and up-to-date information about movies, showtimes, theaters, and ticket availability is essential for users to make informed decisions.
Non-Functional:
List non-functional requirements for the system...
- Performance: Ensuring optimal performance is crucial for providing a seamless user experience, especially during peak booking periods. The system should be able to handle high traffic volumes efficiently while maintaining low latency.
- Security: Data security is paramount in an online ticketing platform to protect user information, payment details, and sensitive data from unauthorized access or breaches. Implementing robust security measures, encryption, and access controls are essential.
- Scalability: Designing the platform to be scalable ensures that it can grow with the increasing user base and ticket transactions. Horizontal scalability allows the system to handle additional load by adding more resources without affecting performance.
- Reliability: Maintaining high system reliability is crucial to prevent downtime and ensure continuous availability for users. Implementing fault tolerance mechanisms and proactive monitoring can help minimize disruptions.
- Usability: Prioritizing usability ensures that the platform is easy to use and navigate for all users, irrespective of their technical expertise. A user-friendly interface and smooth booking process enhance user satisfaction.
Capacity estimation
Estimate the scale of the system you are going to design...
Assumptions:
- Let's assume 1 million active users
- During peak hours, the traffic will increase by 10x
- On average 10k events are listed on the website
Estimations:
- Concurrent users: 1m / (24 * 3600) = 11.57 users / second
- Each day every user make 3 requests on average
- So the QPS is 11.57 * 3 = 34.7
This can be handled using single server. Even during peak hours we can easily scale by adding a load balancer.
Data storage estimation:
- For each user we allocate 100KB for storing profile data and tickets data. We store the data for 5 years.
- 1m * 100 KB * 5 = 500GB
- We use 500 KB data for each event/tickets, so events data: 10k * 5 * 500 KB = 25GB
API design
Define what APIs are expected from the system...
We have 4 APIs here. 1 for viewing events and 2 for booking tickets.
We use GET endpoint that takes in an eventID and return the details of that event.
GET /events/details/{eventId}
->
{
eventId,
city,
venue,
performer,
date,
tickets []
...
}
The ticket booking process is divided into two steps:
The user first chooses a specific seat or ticket to buy.
They then progress to a payment page to complete the purchase.
We want to guarantee that once a user selects a ticket, it is reserved for them until they complete the purchase, preventing it from being bought by someone else while they try to check out.
We’re going to need two API endpoints, one for each of the steps in the process:
POST /booking/reserve
->
{
bookingId,
ticektIds []
}
POST /booking/confirm
->
{
bookingId,
isSuccess
}
For search, we just need a single GET endpoint that takes a set of parameters and returns a list of events that match those parameters.
GET /events/search?keyword=&start=&end=&city=&page=
->
{
eventIds []
}
Database design
Defining the system data model early on will clarify how data will flow among different components of the system. Also you could draw an ER diagram using the diagramming tool to enhance your design...
classDiagram
class Users {
- UserID: string
- UserName: string
- Email: string
- PasswordHash: string
...
}
class Events {
- EventID: string
- EventName: string
- Description: string
- Cast: string
- Genre: string
- TrailerURL: string
- VenueID: string
...
}
class Venues {
- VenueID: string
- VenueName: string
- CityID: string
...
}
class City {
- CityID: string
- CityName: string
...
}
class Bookings {
- BookingID: string
- UserID: string
- EventID: string
- SeatIDs: array
- BookingDate: datetime
...
}
class PaymentInformation {
- PaymentID: string
- BookingID: string
- Amount: float
- PaymentDate: datetime
- PaymentStatus: string
...
}
class Seats {
- SeatID: string
- EventID: string
- VenueIDID: string
- SeatNumber: string
- SeatStatus: string
...
}
Users --o Bookings
Users --o PaymentInformation
Bookings --o Seats
Bookings --o Events
Venues --o City
Events --o Venues
Events --o Seats
Seats --o Venues
PaymentInformation --o Bookings
High-level design
You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design...
- User Interface (UI):
- Components:
- Home Page
- Movie/Event Listings
- User Authentication & Registration
- Booking and Payment Interface
- User Profile Management
- Application Layer:
- Components:
- Ticketing Service:
- Manages ticket booking, availability, and seat selection.
- Event Service:
- Handles event details, trailers, and metadata.
- User Service:
- Manages user profiles, authentication, and reviews.
- Search Service:
- Handles search events and cinema locations and city details.
- Booking Engine:
- Components:
- Real-time Booking System
- Seat Selection and Availability Management
- Integration with Payment Gateway
- Database Layer:
- Databases:
- Relational Database (Users, Bookings, Payment Information)
- NoSQL Database (Events, Locations, Reviews)
- External Integrations:
- Components:
- Payment Gateway Integration
- Cinema Partner APIs (for real-time seat availability)
- User Authentication (OAuth, JWT)
- Infrastructure and Scalability:
- Components:
- Load Balancers for distributing traffic
- Caching (Redis/Memcached) for frequently accessed data
- Horizontal Scaling with Clusters for databases
- CDN for media files and trailers
- Message Queue (e.g., Kafka):
- Facilitates asynchronous event processing.
- Allows decoupling of services, enabling scalability and fault tolerance.
- Scheduler Service:
- Manages scheduled jobs, such as updating show timings or sending notifications.
- Integrates with the message queue for event-driven processing.
- Search Engine (e.g., Elasticsearch):
- Indexes and provides efficient searching for events, locations, and metadata.
- Supports fast and relevant search results for users.
Request flows
Explain how the request flows from end to end in your high level design. Also you could draw a sequence diagram using the diagramming tool to enhance your explanation...
sequenceDiagram
participant User
participant UI as "User Interface"
participant Search as "Search Service"
participant Ticketing as "Ticketing Service"
participant Booking as "Booking Engine"
participant Database as "Event Database"
participant CinemaAPI as "Cinema Partner API"
participant PaymentGateway as "Payment Gateway"
User ->> UI: Opens App
UI ->> UI: Displays Movie List
User ->> UI: Searches for a Movie
UI ->> Search: SearchMovie("Avengers")
Search -->> UI: Returns Search Results
UI ->> UI: Displays Search Results
User ->> UI: Selects Movie (Avengers)
UI ->> Ticketing: GetMovieDetails("Avengers")
Ticketing -->> UI: Returns Movie Details
UI ->> Ticketing: GetAvailableShowtimes("Avengers", "CityA")
Ticketing -->> UI: Returns Showtimes
User ->> UI: Selects Showtime
UI ->> Ticketing: GetSeatAvailability("Avengers", "CityA", "Showtime1")
Ticketing -->> UI: Returns Available Seats
User ->> UI: Selects Seats
UI ->> Ticketing: BookSeats("Avengers", "CityA", "Showtime1", ["A1", "A2"])
Ticketing -->> Booking: CreateBookingRequest("Avengers", "CityA", "Showtime1", ["A1", "A2"])
Booking -->> Ticketing: ConfirmBooking("BookingID123")
Ticketing -->> PaymentGateway: ProcessPayment("BookingID123", "Amount")
PaymentGateway -->> Ticketing: PaymentConfirmation("BookingID123", "Success")
UI ->> UI: Displays Booking Confirmation
Detailed component design
Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...
How do we handle the conflict when multiple users select the same seat while booking a ticket?
- A user will select a seat from the interactive seat map. This will trigger a POST /booking/checkout with the ticketId associated with that seat.
- The request will be forwarded from our load balancer, to our API gateway, and onto the Booking Service.
- The Booking Service will lock that ticket by adding it to our Redis Distributed Lock with a TTL of 10 minutes (this is how long we will hold the ticket for).
- The Booking Service will also write a new booking entry in the DB with a status of in-progress.
- We will then respond to the user with their newly created bookingId and route the client to a the payment page.
- If the user stops here, then after 10 minutes the lock is auto-released and the ticket is available for another user to purchase.
- The user will fill out their payment details and click “Purchase.” In doing so, the payment (along with the bookingId) gets sent to Stripe for processing and Stripe responds via webhook that the payment was successful.
- Upon successful payment confirmation from Stripe, our system's webhook retrieves the bookingId embedded within the Stripe metadata. With this bookingId, the webhook initiates a database transaction to concurrently update the Ticket and Booking tables. Specifically, the status of the ticket linked to the booking is changed to "sold" in the Ticket table. Simultaneously, the corresponding booking entry in the Booking table is marked as "confirmed."
- Now the ticket is booked!
How the system would handle sudden spikes in traffic or ensure high availability during peak hours?
- Load Balancing: Implement load balancing across multiple servers to evenly distribute incoming traffic.Preventing any single server from becoming a bottleneck and ensuring optimal resource utilization.
- Horizontal Scaling and Auto-Scaling in Cloud Environment: Leverage auto-scaling features provided by cloud platforms to automatically adjust the number of server instances based on demand. Ensures that the system can dynamically scale up or down to handle varying levels of traffic, maximizing availability and minimizing costs during low-traffic periods.
- Read/Write Separation: Implement read/write separation by directing read operations to read replicas and write operations to the primary database. This enhances database performance by distributing read and write workloads, ensuring high availability and efficient resource utilization.
Trade offs/Tech choices
Explain any trade offs you have made and why you made certain tech choices...
- Relational Database for User, Booking, and Payment Data:
- Reasoning: User data and booking information require strong consistency and relational structure to maintain data integrity and enforce ACID properties.
- Database Type: Relational Database (e.g., PostgreSQL, MySQL).
- CAP Theorem Focus: Consistency is prioritized to ensure accurate and reliable user information and booking details.
- NoSQL Database for Event, Location, Reviews, and Comments Data:
- Reasoning: Event details and location information may vary and evolve, requiring a flexible schema and scalability, making NoSQL databases suitable.
- Database Type: NoSQL Database (e.g., MongoDB, Cassandra).
- CAP Theorem Focus: Partition tolerance and availability are crucial to handle potential changes in data structure and support scalable operations.
Failure scenarios/bottlenecks
Try to discuss as many failure scenarios/bottlenecks as possible.
How to handle cases where a user may exit the ticket booking process midway, particularly regarding seat reservations or session handling to maintain booking consistency
- Session Timeout and Seat Release:
- To handle scenarios where the user exits the process midway, we can implement session management with a defined timeout.
- If a user is inactive for a specified period during the booking process, the session expires, and any temporary seat reservations associated with that session are released.
- We can also implement a periodic garbage collection mechanism to identify and remove stale or expired sessions. This ensures that temporary seat reservations associated with inactive or incomplete sessions are released and do not persist indefinitely.
- Along with this, the Notification service can notify users about session expiration and seat release through in-app messages or email reminders to improve transparency and manage user expectations.
What happens when a payment fails for a user?
- Payment Failure Handling:
- If a payment fails during the booking process, the Booking Engine should initiate a rollback to cancel the booking transaction.
- The user should be notified about the payment failure, and the booked seats should be released for others to book.
Future improvements
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?
- Introduce Caching Mechanism:
- Implement a distributed caching system to store frequently accessed data, enhancing response times and reducing database load, especially for static information like movie details and city locations.
- Implement Asynchronous Processing:
- Introduce message queues for asynchronous processing of tasks such as payment confirmations and notifications, improving system responsiveness and fault tolerance by decoupling time-consuming operations from user interactions.
- Enhance User Personalization:
- Integrate a recommendation engine that analyzes user preferences and behavior, providing personalized movie suggestions, thereby enriching the user experience and increasing engagement.
- Real-time Analytics Dashboard:
- Develop a real-time analytics dashboard to monitor user behavior, system performance, and booking trends, empowering administrators with valuable insights for data-driven decision-making and continuous system optimization.