System requirements


Functional:

user can reserve a ticket for a specific seat

once selected, the users seat is held until checkout or 10 min expiration


Non-Functional:

users can not reserve the same seat

CP = consistency is important

handle spikes in load




Capacity estimation

Estimate the scale of the system you are going to design...






API design

Define what APIs are expected from the system...


GET /events/id/seats


POST /reserve {

eventid

seats[]

}


DELETE /reserve/id



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...


Use an OLTP DB for consistency


Event {

id

date

title

description

}


Seat {

eventid

seatnum

status

price

}


Reservation {

userid

eventid

}


ReservationSeats {

reservationid,

seatid

}



High-level design


API Gateway handles load balancing, auth, security and forwards requests to api server


API servers are stateless, horizontally scalable


Redis instances and DB can be regionalized, with events tied to clusters. On event creation, redis is populated with the seat data. API server uses Redis to check for reservation states . The updates are committed to the db, and updated in redis on change.


The DB is replicated for availability and failure tolerance


A queue like kafka is added for large/popular events. Limiting the number of users who can make reservations at a time.


SSE are used to update client's seat availability maps



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...


Client request for available seats is made via API gateway and if the current reserving users are over the limit, the user is added to the queue. Client is informed to update to display queue status.


An SSE connection is established to communicate queue status and seat availability to the user.


When user is available to make reservations, an updated seat list is sent to the client. When the user selects seats, those are marked "pending" in redis with an expiration of 10 minutes. If checkout occurs within that timeframe, the seats are marked "reserved"



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...






Trade offs/Tech choices

Explain any trade offs you have made and why you made certain tech choices...


SQL vs NoSQL. Chose SQL for consistency and because the scale can be limited be regionalizing events.

Was this necessary with redis handling the bulk of the updates load?



Failure scenarios/bottlenecks

High load:

Popular events will invite massive load.

Our queue with mitigate issues related to that.


Tickets pending but never checked out:

When expired in redis, they will then become available for purchase again by updating their status in redis and the db


API server down:

The SSE connection will need to be reestablished


Concurrent seat reservations:

if users try to reserve the same seat, the first user to add to their order wins. The update from "available" to "pending" is committed to the DB via transaction and updated in redis. When that availability change is sent via SSE, client will notify user if a seat they have is no longer available



Future improvements