Skip to main content
Articles/System Design/system-design-hld-hotel-booking-example
Scenario Article

System Design HLD Example: Hotel Booking System (Airbnb)

The New Year's Eve Nightmare

Abstract Algorithms•Mar 28, 2026
💡 Executive Summary

A robust hotel booking system must guarantee atomicity in inventory subtraction.

🎯 System Scenario & Requirements

System Goal

A robust hotel booking system must guarantee atomicity in inventory subtraction.

Actors & Components

  • Edge Traffic Ingress
  • Stateless Microservices
  • Datastore Infrastructure
  • API Gateway
  • Domain Service
  • Redis Cache
  • Transactional DB

Functional Requirements

  • TLDR: A robust hotel booking system must guarantee atomicity in inventory subtraction.
  • The core trade-off is Consistency vs.
  • Availability : we prioritize strong consistency for the booking path (PostgreSQL with Optimistic Locking) while allowing eventual consistency and high availability for the search path (Elasticsearch).

Constraints & Assumptions

  • Critical Failure Mode — The Hold-Expiry and Payment Gap: A guest places a hold, begins payment, and the payment takes 16 minutes (possible with 3D Secure strong authentication).
  • The hold expires at 15 minutes.

⚡ Execution Stages & Decision Trace

1

Stage 1 — Global Reservation Systems: Use Cases & Requirements

Action / Decision:

Actors - Guest / Traveler: Searches for rooms, views availability, and makes reservations.

Component Behavior:

- Host / Property Manager: Manages inventory, sets pricing, and views upcoming bookings.

Observable Output: - Admin: Handles disputes, refunds, and platform-wide monitoring.
Read Full Stage in Deep Dive ↓
📖

Deep Dive

Detailed Architectural Analysis

Scenario context

A robust hotel booking system must guarantee atomicity in inventory subtraction. The core trade-off is Consistency vs. Availability: we prioritize strong consistency for the booking path (PostgreSQL with Optimistic Locking) while allowing eventual consistency and high availability for the search path (Elasticsearch). A two-phase "Hold-then-Confirm" model ensures that inventory isn't leaked during payment failure…

This walkthrough focuses on The New Year's Eve Nightmare.

Before making a design choice, clarify:

  • Imagine it’s 11:59 PM on New Year’s Eve.
  • Two different travelers, one in London and one in New York, are looking at the exact same penthouse in Manhattan for the upcoming weekend.
  • Both click "Book Now" at the same millisecond.

Concepts in play: system-design-hld-architectures, caching, sorting-and-searching-algorithms, consistency-replication

Stage 1 — Global Reservation Systems: Use Cases & Requirements

  • Actors - Guest / Traveler: Searches for rooms, views availability, and makes reservations.
    • Host / Property Manager: Manages inventory, sets pricing, and views upcoming bookings.
    • Admin: Handles disputes, refunds, and platform-wide monitoring.
  • Functional Requirements - Search: Users can search rooms by location (geo-coordinates), date range, and guest count.

Observable outcome: Functional Requirements - Search: Users can search rooms by location (geo-coordinates), date range, and guest count.

Stage 2 — Basics: Baseline Architecture

  • At its core, a booking system is an Inventory Management Engine .
  • Unlike a standard e-commerce site where you might have 1,000 units of a SKU, a hotel booking system has "Perishable Inventory." A room night on December 31st is a different "product" than the same room on January 1st.
  • The baseline architecture involves: 1.
  • Inventory Generation: Pre-calculating available slots for every room for the next 365 days.

Observable outcome: Inventory Generation: Pre-calculating available slots for every room for the next 365 days.

Stage 3 — Mechanics: Distribution & Processing Logic

  • The distribution of inventory must be handled carefully.
  • When a host adds a new listing, we don't just add one row.
  • We must generate 365 rows in the availability slots table.
    • Inventory Fan-out: Every update to a room's base availability (e.g., taking the room offline for maintenance) must propagate to all 365 days.

Observable outcome: - Inventory Fan-out: Every update to a room's base availability (e.g., taking the room offline for maintenance) must propagate to all 365 days.

Stage 4 — Estimations & Design Goals

  • The Math of Inventory - Total Listings: 10 Million rooms.
    • Booking Window: 1 year (365 days).
    • Total Inventory Rows: 10M 365 = 3.65 Billion rows .
    • Search-to-Booking Ratio: 20:1.

Observable outcome: - Search-to-Booking Ratio: 20:1.

Stage 5 — High-Level Design: Separating Search from Booking

  • The following architecture ensures that high-volume search traffic never interferes with the critical booking path.
  • The diagram captures the defining architectural decision: a hard separation between the Search Path (Elasticsearch + Redis) and the Booking Path (Postgres with SELECT FOR UPDATE SKIP LOCKED).
  • The CDC pipeline via Debezium keeps the two paths synchronized without coupling them — a booking written to Postgres propagates to Elasticsearch within 1–2 seconds, keeping search results fresh while ensuring the bookin…
graph TD
    User((User)) --> LB[Load Balancer]
    LB --> AG[API Gateway]

    subgraph Search_Path
        AG --> SS[Search Service]
        SS --> ES[(Elasticsearch: Geo + Dates)]
        SS --> RC[(Search Cache: Redis)]
    end

    subgraph Booking_Path
        AG --> BS[Booking Service]
        BS --> AS[Availability Service]
        AS --> PDB[(Primary DB: Postgres)]
        BS --> PS[Payment Service]
    end

    subgraph Async_Sync
        PDB --> CDC[Debezium / CDC]
        CDC --> Kafka[Kafka]
        Kafka --> SS
        Kafka --> NS[Notification Service]
    end

Observable outcome: The CDC pipeline via Debezium keeps the two paths synchronized without coupling them — a booking written to Postgres propagates to Elasticsearch within 1–2 seconds, keeping search results fresh while ensuring the bookin…

Stage 6 — Deep Dive: How Postgres Atomically Prevents the Double-Booking Race Condition

  • The Hold mechanism is the most critical internal component.
  • Understanding exactly how it works at the database level reveals why no amount of application-level locking can replace it — only the database can guarantee atomicity across concurrent transactions.
  • Internals: The Hold-then-Confirm State Machine When a guest selects a room and date range, the Booking Service must atomically transition N rows in the availability slots table (one per night) from AVAILABLE to HELD .
  • The key word is "atomically": if any single night in the requested range is already HELD or BOOKED by another session, the entire operation must roll back with no writes committed.

Observable outcome: The key word is "atomically": if any single night in the requested range is already HELD or BOOKED by another session, the entire operation must roll back with no writes committed.

End-to-end outcome

After working through the stages, you should be able to explain:

  • Lesson 1 — The hold is your correctness anchor.
  • Every architectural decision should be evaluated against one question: "Does this preserve the integrity of the hold?" Adding a caching layer between the Booking Service and Postgres is dangerous if the cached availabil…

Alternatives considered

The source focuses on one primary design. A second architecture is not compared, so no alternative is invented here.

Failure and degraded modes

Consistency vs. Availability: Trade-offs in the Booking Path

  • Detection: Critical Failure Mode — The Hold-Expiry and Payment Gap: A guest places a hold, begins payment, and the payment takes 16 minutes (possible with 3D Secure strong authentication).
  • User or operator impact: Critical Failure Mode — The Hold-Expiry and Payment Gap: A guest places a hold, begins payment, and the payment takes 16 minutes (possible with 3D Secure strong authentication).

Share this case study

Discuss architecture trade-offs and lessons with your team.

Share:XLinkedInReddit