Hotel Booking System | Airbnb System Design| Most frequently asked question in technical interviews
In this article we are going discuss about a famous System Design Interview Question. Design a Hotel Booking System or Design Airbnb etc.
Try to take all inputs about functional and non-functional requirements from the interviewer to avoid confusion at the later stage. Do ask questions to keep the requirements clear.
Airbnb is a online platform which associates individuals who need to rent out their houses through individuals who are looking for lodgings and rooms in a place/city.
First let us understand the functional and the non functional requirements.
Functional Requirements
We have two main actors in this system, one is Hotel Manager who feeds data to the system about hotel and it’s availability and other is the customer who wants to book the hotel room.
Hotel Manager
1. Actor should be able to register Hotel on the platform.
2. Actor should be able to add/update/delete Room Types in the Hotel.
3. Actor should be able to add/update/delete Room of given Room Type.
4. Actor should be able to define the price and inventory of room types on daily basis.
Customer
1. Actor should be able to search available hotels by city, check-in, check-out date.
2. Actor should be able to select a hotel and see all the available hotel types and their prices.
3. Actor should be able to select the desired room type and proceed for the booking.
4. Actor should receive the notification about the booking details once the booking is completed.
Non Functional Requirement
1. System handling operations related to Hotel Managers and booking flows should be Highly Consistent
2. Discovery Platform showing hotels to the customers should be Highly Available
3. System should have low latency
4. System should be Highly Scalable with increase in number of restaurants and customers
5. System should be able to handle concurrent requests such that no two customers should be able to book the same room on a particular day
Once we’ve detailed about the functional requirements we can either proceed with High Level Diagram or DB schema depending on how the interviewer asks. For now, let’s proceed with DB Schema/Entity Design.
Tables
location
- id PK
- address text
- latitude double
- longitude double facility
- id PK
- name varchar
- UK (name)hotel
- id PK
- name varchar
- location_id FK
- description texthotel_facility
- id PK
- hotel_id FK
- facility_id FK
- UK (hotel_id, facility_id)room_type
- id PK
- name varchar
- description text
- hotel_id FKroom
- id PK
- room_type_id FK
- room_number varchar
- current_booking_id
- status enum (BOOKED/AVAILABLE)room_type_facility
- id PK
- room_type_id FK
- facility_id FK
- UK (room_type_id, facility)id)room_inventory
- id PK
- hotel_id FK
- room_type_id FK
- date datetime
- total_count integer
- available_count integer
- constraint (available_count ≥ 0)booking
- id PK
- user_id FK
- hotel_id FK
- room_type_id FK
- checkin_date datetime
- checkout_date datetime
- invoice_id UK
Now let’s check if our functional requirement can be satisfied from the above designed models.
Let’s figure out the core REST APIs that will be required for this system
- Register hotel on the platform
POST /hotel/register - Add Room Type in a Hotel
POST /hotel/{hotel_id}/room-type - Add Room In Hotel
POST /hotel/{hotel_id}/room-type/{room_type_id}/room - Return the list of nearby hotels
GET /hotels/location/{location_id} - Given a hotel return it’s detail
GET /hotel/{hotel_id} - Book a hotel room
POST /booking - Return the bookings for a user
GET /user/{user_id}/bookings - Returns the bookings for a hotel
GET /hotel/{hotel_id}/bookings - Check-In to hotel
PUT /booking/{booking_id}/check-in - Check-Out from hotel
PUT /booking/{booking_id}/check-out
APIs 1,2,3 will be part of Hotel Management Service.
APIs 4,5 will be part of Discover Platform.
APIs 6,9,10 will be part of Booking Service.
APIs 7,8 will be part of Booking History Service.
So as per the above description it’s clear that this system will have at-least 3 micro-services which will work together to provide us a platform.
Let’s discuss about the high level architecture of the system
End to End Flow
- Hotel Manager will manage details about hotel, room-type, rooms and define room inventory and prices from his Hotel Manager App.
- Hotel manager will publish the details, this will send an event to Async Queue which will then consumed by AWS Lambda function which indexes the hotel info to elasticsearch and becomes available to user on the user app.
- User can search for hotels on the User App and select the preferred room-type.
- User can book the selected room from his User app and can see the current and past booking.
Hotel Service
It handles all the operations related to hotel management like registering hotel, adding room-type, adding room, update room type prices and inventory. It uses Postgres as it’s DataSource as the data is limited and can fit onto a single machine. It also uses Redis to cache all the frequently used static information.
AWS Lambda/Indexing Service
This service reads the event from Queue and gets the data from PostgreSQL of Hotel Service to create the Json to be indexed to ElasticSearch. AWS Lambda provides on demand scaling.
Discover/Search Service
This service provides the full text search and capability to find the nearby hotels for a given location. It utilises the power of Elasticsearch to perform its task.
Booking Service
This service handles the booking flow of the system. Consistency is preferred over availability to handle overbooking of a room on a single day.
Archival Service
This service takes all the non-active booking data from postgres and dumps it into cassandra.
Booking History Service
This service returns list of current and past booking based on the given filter.
It fetches data from PostgreSQL for the current booking and Cassandra for past bookings.
All the Services can auto scale Horizontally to handle the load
Booking Workflow
- App sends following payload to Booking Service
{
“user_id”: 123,
“hotel_id”: 234,
“room_type_id”: 456,
“checkin_date”: “today”,
“checkout_date”: “today + 4”
} - Booking Service validates the data for the room availability
select * from room_inventory where room_type_id = {room_type_id} and date ≥ {checkin_date} and date ≤ {checkout_date} and available_count > 0;
if it returns the number of rows equal to diff in checkin and checkout dates, we proceed further otherwise throw aRoomNotAvailable
Exception - It creates a row in
booking
table - Reduces available count by 1 for all rows returned in Point 2
All the 4 steps happen inside a transaction so that if any issue occurs then everything is rolled back.
But how does it solve concurrency?? Assume if there is a room type with availability_count
as 1 and 2 users are trying to book the same room and at the same time. As per the above workflow, if both requests come at the same time, then the same room will be booked by both the users.
How to solve this concurrency issue ??
We set the transaction isolation level to Serializable. After this, every transaction takes a write lock on the range of rows it gets in Step 2 till the time the transaction is committed. By that time all other transactions trying to read the same range of rows will wait until the transaction who has taken the lock is completed. This ensures that no two concurrent request can access the same rows of room inventory. Hence, it resolves the concurrency issue.
Google search about transaction isolation level and how it’s implemented
And this is all about the system design of the Airbnb.
Hit Clap if you liked the explanation and do comment your doubts if any :)