Bird
Raised Fist0

Design a Hotel Booking System - Inventory, Reservation, Double Booking Prevention

HLDhardInterview freq: high
Choose your preparation mode4 modes available
🏗️
Design a Hotel Booking System - Inventory, Reservation, Double Booking Prevention
Design a scalable hotel booking system with real-time inventory management and double booking prevention
hardSearch and DiscoveryFreq: high
Prerequisites:Inverted IndexElasticsearch
⚙️
Functional Requirements
  • Search hotels by location, date, and room type with availability filtering
  • Real-time inventory management reflecting room availability per hotel
  • Reservation creation with atomic booking to prevent double bookings
  • Reservation cancellation and modification with inventory updates
  • User notification on booking confirmation or failure
  • Support for multiple room types and dynamic pricing
📊
Non-Functional Requirements
  • Support 50 million daily active users (DAU) with peak 1 million concurrent bookings
  • Reservation write latency under 100ms P99 for a smooth user experience
  • System availability of 99.99% to ensure booking reliability
  • Data consistency for inventory to prevent double bookings with strong consistency guarantees
  • Scalable to handle 10x growth in traffic without major redesign
❓
Clarifying Questions to Ask
  • What is the expected peak QPS for booking requests and search queries?
  • Are partial bookings (e.g., some rooms in a multi-room request) allowed?
  • Is eventual consistency acceptable for search results or must availability be strongly consistent?
  • What is the expected retention period for reservation and inventory data?
  • Are there any SLAs for inventory synchronization with hotel property management systems?
  • Should the system support overbooking policies or strictly prevent double bookings?
Out of Scope
✗ Payment processing and gateway integration
✗ User profile management and authentication
✗ Hotel onboarding and content management
✗ Review and rating system
📌
Assumptions
  • 50 million DAU with average 20 booking-related actions per user per day
  • Average booking request size 500 bytes including metadata
  • Peak booking write QPS is 5% of total daily writes concentrated in 4 peak hours
  • Search read QPS is 10x write QPS due to browsing and availability checks
⚡
QPS Calculation
write qps50M users × 20 actions/day ÷ 86400 sec ≈ 11,574 writes/sec
peak write qps11,574 × 10 (peak factor) ≈ 115,740 writes/sec
read qps115,740 × 10 (read to write ratio) ≈ 1,157,400 reads/sec
💾
Storage Estimate
daily storage11,574 writes/sec × 500 bytes × 86400 sec ≈ 500 GB/day
retention days365
total storage500 GB/day × 365 days × 3 (replication factor) ≈ 547.5 TB
🖥️
Server Estimate
booking serviceAssuming 1000 writes/sec per server, need ~116 booking servers for peak write QPS
search serviceAssuming 10,000 reads/sec per Elasticsearch node, need ~116 Elasticsearch nodes
🏗️
Architecture Diagram
Architecture Diagram
          +----------------+
          |   User Client  |
          +-------+--------+
                  |
          +-------v--------+
          |  API Gateway   |
          +-------+--------+
                  |
      +-----------+------------+
      |                        |
+-----v-----+           +------v-------+
| Booking  |           | Search Svc   |
| Service  |           | (Elasticsearch)|
+-----+----+           +------+-------+
      |                        |
      |                        |
      |                +-------v--------+
      |                | Inventory DB   |
      |                | (Cassandra)    |
      |                +-------+--------+
      |                        |
      |                +-------v--------+
      |                | Reservation DB |
      |                | (Cassandra)    |
      |                +----------------+
🧩
Components
API Gateway
Entry point for all client requests, routes to booking or search services
Why thisNginx with Lua scripting for high throughput and flexible routing with low latency
Why notAWS ALB lacks fine-grained routing and custom logic needed for complex request validation
Booking Service
Handles reservation creation, cancellation, and inventory updates with strong consistency
Why thisStateless microservice in Go with distributed locking via Redis RedLock to prevent double bookings
Why notMonolithic app would not scale horizontally and complicate deployment and fault isolation
Search Service
Provides hotel search and availability filtering using inverted indices
Why thisElasticsearch for full-text search and fast filtering on hotel attributes and availability
Why notRelational DB full table scans are too slow for high QPS search queries
Inventory DB
Stores real-time room availability per hotel and room type with high write throughput
Why thisApache Cassandra for linear write scalability and tunable consistency to support strong consistency on critical keys
Why notPostgreSQL B-tree indexes do not scale linearly at 115K writes/sec and require complex sharding
Reservation DB
Stores reservation records with user, hotel, room, and timestamp details
Why thisCassandra for high write throughput and fast range queries on reservation time windows
Why notMongoDB lacks strong consistency guarantees needed to prevent double bookings
Distributed Locking (Redis RedLock)
Ensures atomic reservation creation to prevent double booking on the same room
Why thisRedis RedLock algorithm provides distributed locks with fault tolerance and low latency
Why notZookeeper has higher latency and operational complexity for short-lived locks
🔄
Data Flow
1
User Client → API Gateway
User sends search or booking request
API Gateway routes request based on type
2
API Gateway → Search Service
For search, query Elasticsearch with filters
Returns available hotels and room types
3
API Gateway → Booking Service
For booking, request reservation creation
Booking Service acquires distributed lock on room inventory
4
Booking Service → Inventory DB
Check and decrement room availability atomically
Strong consistency ensures no double booking
5
Booking Service → Reservation DB
Create reservation record after successful inventory update
Reservation data persisted for user and hotel reference
6
Booking Service → Distributed Locking (Redis RedLock)
Release distributed lock after reservation creation
Ensures lock is freed for other booking requests
7
Booking Service → User Client
Send booking confirmation or failure notification
User informed of booking status

Practice

(1/5)
1. In a primary-replica replication system, at step 4 the replica receives a batch of write-ahead log entries from the primary. What is the replica's exact state after applying these entries?
easy
A. Replica marks entries as committed and acknowledges primary before applying
B. Replica applies entries to its data store and then acknowledges primary
C. Replica applies entries and immediately serves reads from them before acknowledgment
D. Replica buffers entries without applying until primary confirms commit

Solution

  1. Step 1: Trace replica behavior at step 4

    Replica applies WAL entries to its local store to catch up with primary.
  2. Step 2: Understand acknowledgment timing

    Replica acknowledges primary only after applying entries to ensure durability and consistency.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Replica applies then acknowledges -> ensures data durability [check]
Hint: Apply WAL entries before ack -> durability ensured [check]
Common Mistakes:
2. In the web crawler's request flow, at Step 5 the Duplicate Detection component receives a URL. What happens if this URL has been seen before?
easy
A. The URL is discarded and not sent to the Scheduler to avoid redundant crawling
B. The URL is immediately re-queued to the Scheduler for crawling again
C. The URL is marked for delayed re-crawl but still sent to the Scheduler
D. The URL is sent to the Politeness Policy Manager to check domain delays

Solution

  1. Step 1: Understand Duplicate Detection behavior at Step 5

    If the URL has been seen before, it is filtered out to prevent redundant crawling.
  2. Step 2: Eliminate other options

    Re-queuing duplicates wastes resources; marking for delayed re-crawl is a separate process; Politeness Policy Manager handles timing, not duplication.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Duplicate Detection discards seen URLs to avoid redundancy [check]
Hint: Duplicate Detection discards duplicates before scheduling [OK]
Common Mistakes:
3. A messaging system must handle 1 million writes per second and guarantee message durability despite server crashes. Which component best ensures durability without blocking producers?
easy
A. In-memory queue with periodic disk snapshots
B. Distributed log like Apache Kafka with partitioned topics
C. Simple Redis list with persistence disabled
D. Direct synchronous writes to a relational database

Solution

  1. Step 1: Identify durability and high write throughput needs

    In-memory queues with snapshots (A) risk data loss on crash; Redis without persistence (C) loses data on restart; synchronous DB writes (D) block producers and limit throughput.
  2. Step 2: Evaluate Kafka's distributed log

    Kafka partitions topics for parallelism and persists data durably on disk, allowing high throughput and crash recovery without blocking producers.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Kafka partitions + durable log -> high throughput + durability [check]
Hint: Durable logs handle high writes without blocking producers [OK]
Common Mistakes:
4. A messaging system must decouple high-throughput message producers from multiple independent consumers subscribing to different topics. Which component best handles this decoupling and ensures message durability?
easy
A. Use a distributed log-based system like Kafka with topic partitions
B. Use a simple in-memory queue on the producer server to buffer messages
C. Use a direct HTTP push from producer to each consumer
D. Use a relational database with polling by consumers

Solution

  1. Step 1: Identify decoupling and durability needs

    In-memory queues (Use a simple in-memory queue on the producer server to buffer messages) lack durability and don't scale across servers. Direct HTTP push (Use a direct HTTP push from producer to each consumer) tightly couples producer and consumers, causing backpressure issues. Polling a relational DB (Use a relational database with polling by consumers) adds latency and load on DB, unsuitable for high throughput.
  2. Step 2: Recognize Kafka's role

    Kafka's distributed log with topic partitions decouples producers and consumers, provides durability, and supports high throughput with consumer groups.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Kafka partitions enable durable, scalable decoupling [check]
Hint: Distributed logs decouple producers and consumers reliably [OK]
Common Mistakes:
5. For real-time message delivery to mobile clients with intermittent connectivity, which architecture best balances latency and resource usage?
medium
A. Use gRPC streaming connections from server to mobile clients
B. Use WebSocket connections with heartbeat and fallback to push notifications
C. Use long polling HTTP requests from clients to server
D. Use MQTT protocol with persistent sessions for mobile clients

Solution

  1. Step 1: Evaluate WebSocket vs gRPC streaming for mobile clients

    gRPC streaming is efficient but poorly supported on many mobile platforms; WebSocket is widely supported with heartbeat to detect disconnects.
  2. Step 2: Consider fallback mechanisms

    WebSocket with push notification fallback handles intermittent connectivity better than long polling or MQTT, which have higher overhead or complexity.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    WebSocket + push fallback balances latency and mobile constraints [check]
Hint: WebSocket + push fallback handles mobile connectivity best [check]
Common Mistakes:
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard