Katkat

Design Caching for a Hotel Booking System

Fora TravelSoftware Engineer · Onsite

Last updated

Design a high-throughput caching and inventory architecture for a hotel booking platform that accelerates read-heavy search traffic while strictly preventing overselling through temporary holds and authoritative consistency.

Scenario

You are tasked with designing the caching and inventory management architecture for a hotel booking platform. The platform experiences high-volume, read-heavy search traffic for destination availability and pricing. However, actual bookings require strict consistency: two users must never book the same physical room for overlapping dates (zero double-booking).

Your design needs to bridge fast, potentially stale read caches with an authoritative transactional booking engine.

Requirements

Functional Requirements

  • Search & Discovery: Users can search for available hotels and rooms by city, check-in/check-out dates, and guest count.
  • Room Details & Price Quoting: Users can view up-to-date pricing and room details.
  • Temporary Inventory Hold: When a user proceeds to the checkout screen, the room must be placed on a temporary hold (e.g., 10 minutes) to prevent others from booking it while payment processes.
  • Booking Confirmation: Once payment succeeds, the held room transitions to confirmed. If payment fails or the timer expires, the room is released back to inventory.

Non-Functional Requirements

  • Low Latency: Search and room details endpoints should achieve p95 latency under 100 ms.
  • Zero Overselling: Never confirm two bookings for the same room night.
  • High Availability: Search remains operational even if the booking transaction processor experiences degraded performance.
  • Eventual Consistency with Guardrails: Caching stale pricing or availability during search is acceptable only if the price and availability are authoritatively revalidated before checkout.

Scale Assumptions

  • Total Hotels: 500,000 properties worldwide, averaging 40 rooms per property.
  • Search Traffic: 50 million search requests per day (~600 QPS average, 3,000 QPS peak).
  • Booking Traffic: 100,000 bookings per day (~1.2 QPS average, 15 QPS peak).
  • Read-to-Write Ratio: Approximately 500:1 read-to-write ratio.

Key Areas to Cover

  1. Architecture & Caching Strategy: Multi-tier caching architecture (CDN, distributed cache like Redis, local in-memory caches) separating static metadata (hotel descriptions, photos) from dynamic data (pricing, room availability calendar).
  2. Revalidation & Hold Mechanism: How the system moves a user from a cached search result to an authoritative hold. Detail the state transitions (AVAILABLE -> HELD -> BOOKED).
  3. Concurrency Control & Idempotency: Concurrency primitives (e.g., Redis SETNX with TTL, distributed locks, database row locks/optimistic locking) and idempotency keys during checkout.
  4. Cache Invalidation & Reconciliation: Strategies for updating or invalidating cached availability upon booking, cancellation, or hold expiration.

Hints

Hint 1

Separate static hotel metadata (amenities, photos) from dynamic availability and rates so they can use vastly different cache TTLs and eviction policies.

Hint 2

Tolerate slightly stale availability during the search phase, but require an authoritative, atomic revalidation step the moment the user clicks 'reserve'.

Hint 3

Use atomic operations with automatic expiration (such as Redis key expiration or database row leases) to implement the temporary checkout hold without stranding inventory if a worker crashes.

Follow-up questions

  • How would you prevent a cache stampede (thundering herd) when the availability cache for a popular hotel in a high-demand city expires?
  • If the booking service experiences a network partition while talking to the cache, how does your system guarantee consistency between the database and the cache?
  • How would you adapt this architecture if 30% of your room inventory comes from external third-party suppliers via rate-limited partner APIs?