Alex Xu V2 - 7 Hotel Reservation System


Step 1 - Understand the problem and establish scope

What’s the scale of the system?

Can customers pay when they arrive to the hotel?

Do customers only book through the website?

Can they cancel?

What other things should we consider?

Non functional requirements

Support high concurrency -> During peak season, people booking at same time can occur

Moderate latency -> Fast response time when user makes a reservation, like a few seconds before they get an ACK from the server

Back of the envelope estimation

5,000 hotels. 1 Million rooms in total

70% of rooms are always filled and average stay duration of 3 days

1M * .7 / 3 days -> 233,333 queries/day

QPS -> 2.33/second

QPS of every page in the system

View hotel page -> View booking page -> Reserve a room ->

Let’s assume a 90% loss of users at each step

![[Pasted image 20240213184506.png]]

Propose High Level Design and Get Buy-in

API Design

GET /v1/hotels/ID -> Get info about a hotel POST /v1/hotels -> Add new hotel (only for hotel staff) PUT /v1/hotels/ID -> Update hotel info DELETE /v1/hotels/ID -> Delete a hotel

GET /v1/hotels/ID/rooms/ID -> Get info about a room POST /v1/hotels/ID/rooms -> Add new room (only for hotel staff) PUT /v1/hotels/ID/rooms/ID -> Update room info DELETE /v1/hotels/ID/rooms/ID -> Delete a room

Reservation API

GET /v1/reservations -> Get reservation history for logged in user (some session id?) POST /v1/reservations/ID -> Add new room (only for hotel staff) PUT /v1/hotels/ID/rooms/ID -> Update room info DELETE /v1/hotels/ID/rooms/ID -> Delete a room

Data Models

First let’s look at each query to get a sense of volume

Query 1 -> View hotel info Query 2 -> Find rooms based on date range Query 3 -> Record a Reservation Query 4 -> Look up past reservation or history of reservations

He decides to use a relational database because this is not a write-heavy application

![[Pasted image 20240214072152.png]]

Status is the only weird one here. We do it for locking, recording cancelled, and checking if we’ve refunded yet

High Level Design

![[Pasted image 20240214073749.png]]

CDN to cache the static assets like the HTML pages, images, videos, JS.

Internal APIs -> Only available to hotel staff

Step 3 - Design Deep Dive

Improved Data Model

For a hotel, we use room types, so we need to change the names to room types in our schema

![[Pasted image 20240214082310.png]]

The Reservation service changed significantly though

It has an inventory system that counts the number used and available Core idea here is to give each date X number of rooms and we keep track for each date. Then use a query to get the rooms available on a date.

30 days a month for 12 months, is like 360 entries. If we have like 1,000 hotels / room types, that’s enough to fit inside SQL and quickly give us available data.

But what if we want data is still too big for a single server?

Xu doesn’t mention it, but I image the date will be a secondary key that will allow sorted for key-range queries

![[Pasted image 20240214083219.png]]

We only allow booking at around 110% capacity, so we can add an if statement into the application for this.

Bonus Question -> What to do if reservation data is too much for DB?

Concurrency issues

Need to prevent double bookings

Don’t let the same user click the book button multiple times

Don’t let multiple suers have the same reservation

![[Pasted image 20240214084207.png]]

Previous SQL query

Option 1: Pessimistic Locking

Locks at the start of the update so other users can’t


Xu does not recommend this option

Option 2: Optimistic Locking

Uses timestamps or version numbers to allow both to update the resources

If V2 already exists, don’t commit the update and raise an error to User



Database Constraints

Before doing anything, check the hotel inventory (This is called a constraint in SQL)

If not available it will rollback the transaction Immediately increment the inventory



Because we use SQL, we can’t scale that much

1,000 QPS would be tough, but we can still use sharding

Database Sharding

Shard by hotel_Id

I think there’s more questions to be raised about sharding by location or even talking about secondary keys, but okay


Only the future and current hotel inventory matters

We can use a TTL cache to store inventory, and it’ll auto expire

We can add a cache layer on top of the DB too

Apparently this doesn’t matter because the Database will record everything?

Data Consistency among services

Xu says his approach uses a hybrid monolith / micro-service approach.

Some interviewers will only prefer micro-service architecture

![[Pasted image 20240214092530.png]]

Two Phase Commit Strategy