algomiBlogs
← All posts

Hotel Reservations: How to Promise a Room Only Once

Algomi Research · Created 2026-09-16 · Updated 2026-10-15 · System Design

System Design Case Studies · Part 1 of 15
Airline Management: One Journey, Several Carefully Kept Promises
Page 1 of 1

Two families, one room, and a very awkward Diwali

Kiran's aunt runs a six-room guesthouse in Goa, with one big family room. Last Diwali she took bookings by phone and WhatsApp. Two families called within a minute of each other, both heard "yes, it's free," and both turned up on the 10th with luggage and grandparents. (Kiran, his aunt and every number here are made up for teaching.)

Kiran builds her a booking website so it never happens again. Two years later, the same code runs Konkan Stays, a platform listing 80,000 hotels. This post follows that growth, because every hard part of hotel booking shows up in it:

  • A stay is several promises at once. A three-night booking needs all three nights, or it's worthless.
  • Search and booking are different jobs. Search can be a little out of date. A booking confirmation can never be.
  • Payment is slow and sometimes uncertain, and it must never be allowed to hold the inventory hostage.

In 30 seconds, as an architect would frame it: "The core of a booking system is one invariant: for each room type and night, held plus confirmed never exceeds sellable capacity. I'd store inventory per room type per night, claim every night of a stay in one transaction with a consistent lock order, and turn that claim into a time-limited hold. Payment runs outside that transaction as a tracked workflow, with an idempotency key and reconciliation for uncertain outcomes. Search reads a cache that's allowed to be stale, because the hold transaction makes the final decision."

This is an original interview design, not the internal architecture of any named booking company. It starts with one operator managing several hotels. Marketplace settlement and syncing with external booking channels are extensions.

1. The rules, and the guest who left on the 12th

Kiran's first version had an off-by-one bug. A guest staying "10 to 12 June" blocked the room on the 12th too, so the next guest couldn't arrive that day.

Represent dates as a half-open interval: [check_in, check_out). A stay from 10 June to 12 June uses the nights of the 10th and 11th, and the room is free for a new guest arriving on the 12th.

gantt
    title Half-open stays: the check-out day is free for the next guest
    dateFormat YYYY-MM-DD
    axisFormat %d %b
    section Guest A
    Nights of 10 and 11 June :a1, 2026-06-10, 2d
    section Guest B
    Nights of 12 and 13 June :b1, 2026-06-12, 2d

Reading the diagram. Each bar covers the nights a guest sleeps there. Guest A's bar ends where Guest B's begins, with no overlap and no gap. That's what the half-open interval buys you: "check-out day" and "check-in day" can be the same date without a conflict.

Two more date details:

  • Use the hotel's local calendar for room nights.
  • Store precise event timestamps separately. An accommodation date is not a UTC timestamp rounded to a day. A Goa night and a London night are different calendar objects.

What the system must do. Guests search by location, dates and party size. They see room descriptions and prices, book, view their bookings and cancel under a stated policy. Authorised hotel staff maintain room inventory, rates and reservations. The first design assumes no deliberate overbooking.

Rule Why it matters
Confirm only inventory that was successfully held Search results can be stale
Hold all nights or none A guest cannot use a three-night stay missing the middle night
Preserve the accepted price and currency Rates can change after booking
Do not charge twice for a retry A network response can disappear
Staff changes must respect existing bookings Reducing capacity cannot silently erase promises

The invariant, which every later section protects, is: for each room type and night, held + confirmed <= sellable_capacity.

2. "Room type, or room 204?": the data model

A guest asks for "the sea-view room, please, number 204." Most hotels sell a room type ("deluxe sea view") and assign the physical room at check-in. If the product promises an exact room, you instead need non-overlapping date intervals for that room. Pick one model deliberately, because each needs a different invariant.

Konkan Stays sells room types:

Record Main fields Responsibility
Hotel hotel_id, location, timezone Property information
RoomType type_id, hotel_id, occupancy Category guests can book
InventoryNight type_id, local_date, capacity, held, confirmed Authoritative nightly stock
Quote quote_id, dates, price, currency, expires_at Time-limited price offer
Hold hold_id, quantity, dates, expires_at, state Temporary inventory claim
Booking booking_id, guest_id, hold_id, status, accepted_price Durable reservation
PaymentAttempt attempt_id, booking_id, provider_reference, status External payment outcome
  • InventoryNight is the heart of the system. There is one row per room type per night, holding the counts the invariant is about.
  • Make (type_id, local_date) unique.
  • Money: use integer minor units (paise, cents) or decimals, together with a currency and explicit rounding rules.

3. The smallest design that works

For the aunt's guesthouse, one app and one database are plenty:

Hotel reservation system: step 1, one app, one databaseStep 1 of 3: One app, one database. Components: Guest app, Quotes and holds, Bookings, InventoryNight, Hold and Booking. Start with the core promise: a guest holds a room and books it, and one database decides whether the nights are still free. CLIENTS BOOKING APPLICATION one modular app BOOKING DATABASE the authority Guest app Quotes and holds Bookings confirm, cancel InventoryNight nights left per room type Hold and Booking state machine hold room claim nights record hold confirm, pay call service data store people, apps, external
Step 1: the smallest design that works.

You've reached the free preview of this post.

Subscribe to the Blogs plan (₹99/mo) — or use any Algomi Suite, Career, Investor, or Trader plan — to keep reading.

See plans

Sources

System Design Case Studies · Part 1 of 15
Airline Management: One Journey, Several Carefully Kept Promises