Skip to main content

Classic design · Senior

Hotel booking (Booking/Airbnb)

Classic interview design. Key points: reservations and concurrency.

16 min read · Content reviewed on October 22, 2026

Short answer

Classic interview design. Key points: reservations and concurrency. The classic exercise asks for the reservation system of a hotel chain: show the hotel page and the room detail page, book a room, cancel and manage hotel data. The customer pays the full amount at the time of booking, and hotel search is out of scope.

01 · CONTEXT

Little throughput, a lot of contention

The classic exercise asks for the reservation system of a hotel chain: show the hotel page and the room detail page, book a room, cancel and manage hotel data. The customer pays the full amount at the time of booking, and hotel search is out of scope. There is also a business requirement that complicates inventory: the chain accepts ten percent overbooking, that is, selling more rooms than exist, in the expectation that some customers will cancel.

The reference scale is a chain with five thousand hotels and one million rooms, with 70% occupancy and an average stay of three days. That gives about 240,000 reservations per day, or something like three reservations per second. Going down the funnel, the confirmation page gets about 30 queries per second and the detail page about 300.

The non-functional requirement that weighs most is high concurrency: in peak season or at big events, popular hotels get many customers trying to book the same room. Latency, on the other hand, is moderate: it is acceptable for the system to take a few seconds to process a reservation. That is why this case is, at heart, a concurrent write problem over a small inventory.

02 · MODEL

Book a room type, not a room

A modeling decision changes everything else: the reservation is made at the room-type level, not for a specific room. The customer books, for example, a double room at a hotel for certain dates, and the hotel assigns the physical room later. The inventory table stores, per hotel and room type, how many rooms exist and how many have already been reserved, with one row per date, which makes it simple to query and update a date range. Each reservation, in turn, moves through states: pending, paid, refunded, canceled or rejected. See the data modeling in action in the flow below.

  1. The customer opens the chain's website or app; the request enters through the merchant API, which forwards it to the right service.

    Architecture diagram: Hotel reservation flow
    CLClientnavega
    NWMerchant API
    CPHotel service
    DBHotel catalog
    CPReservations service
    DBReservation and inventory database
  2. The hotel and room pages come from the hotel service, which reads the catalog. This data changes little and does not compete for inventory.

    Architecture diagram: Hotel reservation flow
    CLClient
    NWMerchant API
    CPHotel service
    DBHotel cataloghotel data
    CPReservations service
    DBReservation and inventory database
  3. When the customer chooses a room type and dates, the reservation service generates a pending order with a unique identifier, which goes back to the customer for review.

    Architecture diagram: Hotel reservation flow
    CLClient
    NWMerchant API
    CPHotel service
    DBHotel catalog
    CPReservations servicepending order
    DBReservation and inventory database
  4. On confirmation, the service writes the reservation and updates the inventory in the same relational database, in a single transaction.

    Architecture diagram: Hotel reservation flow
    CLClient
    NWMerchant API
    CPHotel service
    DBHotel catalog
    CPReservations service
    DBReservation and inventory databaseinventory + reservation
  5. If the customer cancels, the reservation changes state and the inventory's reserved quantity decreases, returning the room to stock.

    Architecture diagram: Hotel reservation flow
    CLClient
    NWMerchant API
    CPHotel service
    DBHotel catalog
    CPReservations service
    DBReservation and inventory databaseroom released

03 · DOUBLE CLICK

The same user asking twice

Double selling has two different origins. The first is the same user submitting the reservation more than once, for example by double-clicking the button. The second is several users competing for the same room, covered in the next section. Disabling the button on the client helps, but is not reliable: the user can, for example, disable JavaScript and bypass the check.

The defense that counts is on the server: an API idempotente, which produces the same result no matter how many times it is called. In the book's design, the reservation service generates a unique identifier when creating the order, the client sends it on confirmation, and it is the primary key of the reservations table. If the user clicks again, the second write violates the uniqueness constraint and no duplicate reservation is created.

04 · LAST ROOM

Two users, one room

Suppose only one room is left and the database does not use the serializable isolation level. Two transactions read the inventory, both conclude there is still a vacancy, and each writes its reservation. Since one transaction's changes only become visible to others after the commit, the second still sees the old state. The result is that the system lets both users book, even though there is only one room. Fixing this generally requires some kind of lock or check at write time.

  1. Two users request, almost at the same time, the last room of a type, for the same dates.

    Architecture diagram: Contention for the last room
    CLUser Awants the room
    CLUser Bwants the room
    CPReservations service
    DBInventory database
  2. Each transaction reads the inventory and sees that one room is still free. Neither sees the other, because nothing has been committed yet.

    Architecture diagram: Contention for the last room
    CLUser A
    CLUser B
    CPReservations service
    DBInventory databaseone left
  3. With no protection, both write the reservation and commit. The stock says the room was sold, but two guests are entitled to it.

    Architecture diagram: Contention for the last room
    CLUser A
    CLUser B
    CPReservations service
    DBInventory databasesold twice
  4. With one of the protections active, one transaction goes through and the other is rejected or waits. The rejected user is told that the room was just sold.

    Architecture diagram: Contention for the last room
    CLUser A
    CLUser Brecusado
    CPReservations service
    DBInventory databaseprotegido

With pessimistic locking, the transaction locks the rows it read, and the others wait until it finishes. It is simple and serializes updates, but it can cause deadlock when several resources are locked and it hurts performance when transactions are long. Because of these limits, the book does not recommend it for this system.

With optimistic locking, a version column accompanies the row: on write, the application increments the version and the database checks that the new value is the expected one; if not, the transaction aborts. Without contention it is faster, because nothing is locked. Under heavy contention, only one of the clients manages to write and the others get a version failure and must retry. Since the reservation rate is usually low, the book considers it a good option here.

The third option is a constraint in the database itself, which rejects any state in which the total reserved exceeds the inventory. It is similar to the optimistic approach: easy to implement and suited to low contention, but under heavy contention it produces many failures. The book considers it another good option for the problem.

AbordagemHow it prevents double sellingMain limit
Pessimistic lockingLocks the rows it read; other transactions waitDeadlocks and performance loss with long transactions
Optimistic lockingVersion column; writes only if the version has not changedMany retries under heavy contention
Database constraintThe database rejects reserved stock above inventoryMany failures under heavy contention; rule lives outside the application's version control

05 · SCALE

What if it were an entire travel site?

A common deep-dive question: what if the system served not one chain but a large travel site, with a load a thousand times greater? The services are stateless and scale by adding servers. The database, which concentrates all the state, is the bottleneck and does not scale with just more instances.

The way out is the particionamento of the database. Since almost every query filters by hotel, the natural key is the hotel identifier: a hotel's entire history lives in the same shard, and a reservation touches a single database. In the book's example, with thirty thousand queries per second spread across sixteen shards, each gets about 1,875 per second, within the capacity of a MySQL server.

  1. The availability query, by far the most frequent operation, is answered by the inventory cache, without touching the database.

    Architecture diagram: Reservations at scale: shards and cache
    CLClient
    NWMerchant API
    CPReservations service
    CHInventory cachevacancy query
    DBFragmento A
    DBFragmento B
    CPChange capture
  2. The reservation goes to the shard chosen by the hash of the hotel identifier and is validated by the database.

    Architecture diagram: Reservations at scale: shards and cache
    CLClient
    NWMerchant API
    CPReservations service
    CHInventory cache
    DBFragmento Ahotel shard
    DBFragmento B
    CPChange capture
  3. The database is updated first; a change-capture process reads what changed and sends it to the cache asynchronously.

    Architecture diagram: Reservations at scale: shards and cache
    CLClient
    NWMerchant API
    CPReservations service
    CHInventory cache
    DBFragmento A
    DBFragmento B
    CPChange capturecaptures changes
  4. The cache converges to the database state after a short interval.

    Architecture diagram: Reservations at scale: shards and cache
    CLClient
    NWMerchant API
    CPReservations service
    CHInventory cacheatualizado
    DBFragmento A
    DBFragmento B
    CPChange capture
  5. In that interval the cache may show a room the database has already sold. The reservation reaches the database, which does the final validation and rejects it; the user sees that the room was just sold.

    Architecture diagram: Reservations at scale: shards and cache
    CLClient
    NWMerchant API
    CPReservations service
    CHInventory cachestill shows a vacancy
    DBFragmento A
    DBFragmento B
    CPChange capture

Inventory reads are an order of magnitude more frequent than writes, so a cache in front of the database greatly reduces the load. The book suggests Redis, because TTL and least-recently-used eviction help make good use of memory. Even when Redis shows a vacancy, the reservation is checked against the database, which is the source of truth for stock.

The cost is the consistency between database and cache. The database is updated first and the change flows to the cache asynchronously, through application code or change data capture (CDC), a mechanism that reads changes from the database and applies them in another system. The lag is acceptable, according to the book, as long as the database does the final stock validation.

06 · MICROSERVICES

Consistency across services

In a monolith, several operations fit in a single database transaction. In an architecture based on microservices, each service has its own database, and a logically atomic operation can span several services; so there is no single transaction to guarantee consistency.

The book cites two known ways out for distributed transactions. Two-phase commit (2PC) is blocking: the failure of one node halts progress until it comes back. A saga, on the other hand, is a sequence of local transactions; if a step fails, compensating transactions are run to undo the previous steps.

The book's choice for this problem was pragmatic: a hybrid approach, in which the reservation service handles the reservation and inventory APIs, keeping both tables in the same relational database and taking advantage of ACID properties. Deciding whether the extra complexity of distributing is worth it is, in the book's words, an architect's choice.

Frequently asked questions

What is Hotel booking (Booking/Airbnb)?

Classic interview design. Key points: reservations and concurrency.

What does the Hotel booking (Booking/Airbnb) design cover?

It is organized in these sections: Little throughput, a lot of contention, Book a room type, not a room, The same user asking twice, Two users, one room, What if it were an entire travel site?, and Consistency across services.

How long is Hotel booking (Booking/Airbnb) and what level is it?

It takes about 16 minutes to read and is rated Senior level.

Now design it yourself

Run this case as an interview in the System Design school: you make the decisions, the tutor challenges them and you see how your design scores.