Hotel Booking System Design: Search, Inventory & Reservation Flow
Hotel booking platforms like Booking.com and Expedia handle millions of searches per day, each querying availability across thousands of properties in real time. A single property might receive hundreds of concurrent booking attempts during peak season. Designing a system that returns accurate availability, prevents double-bookings, and supports dynamic pricing is a rich system design challenge.
High-Level Architecture#
A hotel booking system consists of several core services:
- Search & Availability Service — Handles user queries for hotels by location, dates, guests, and filters.
- Inventory Service — Manages room types, counts, and real-time availability.
- Reservation Service — Orchestrates the booking lifecycle from hold to confirmation.
- Pricing Engine — Computes dynamic rates based on demand, seasonality, and competitive data.
- Payment Service — Handles charges, refunds, and integration with payment gateways.
- Review Service — Collects and surfaces guest reviews and ratings.
- Notification Service — Sends confirmation emails, reminders, and cancellation notices.
Search & Availability#
Search is the most read-heavy operation. Users search by city, dates, guest count, and apply filters like star rating, amenities, and price range.
Data Model#
Each property has multiple room types (e.g., Standard King, Deluxe Suite). Each room type has a daily inventory count — the number of rooms available on a given date.
Property: { id, name, location, star_rating, amenities[] }
RoomType: { id, property_id, name, capacity, base_price }
Inventory: { room_type_id, date, total_rooms, booked_rooms }
Search Flow#
- Geo query — Filter properties by location using a geospatial index (PostGIS, Elasticsearch geo queries).
- Availability check — For the requested date range, verify that
total_rooms - booked_rooms > 0for at least one room type on every night of the stay. - Filter & rank — Apply user filters, then rank by relevance (price, rating, distance, promoted listings).
Caching Strategy#
Search results are highly cacheable. Use a multi-layer cache:
- CDN/edge cache for popular city + date combinations (TTL: 5-10 minutes).
- Application cache (Redis) for property metadata and pre-computed availability snapshots.
- Real-time availability is checked at booking time, not search time — stale search results are acceptable as long as the booking flow validates freshly.
Room Inventory Management#
Inventory is the heart of the system. Each room type has a per-date allocation that must be tracked accurately.
Inventory Table Design#
room_inventory (
room_type_id UUID,
date DATE,
total_rooms INT,
booked_rooms INT,
blocked_rooms INT, -- maintenance, VIP holds
PRIMARY KEY (room_type_id, date)
)
Hotels can bulk-update inventory through an admin portal. Changes propagate to the search index asynchronously via CDC (Change Data Capture) or event streams.
Overbooking Strategy#
Some hotels intentionally overbook by 5-10%, similar to airlines, expecting cancellations and no-shows. The system supports an overbooking margin per room type that allows booked_rooms to exceed total_rooms within a configured threshold.
Double-Booking Prevention#
This is the single most critical correctness requirement. Two users must never confirm the same last room.
Optimistic Locking with Version Check#
UPDATE room_inventory
SET booked_rooms = booked_rooms + 1, version = version + 1
WHERE room_type_id = ? AND date = ? AND booked_rooms < total_rooms AND version = ?
If the update affects zero rows, the room was taken — the booking attempt fails gracefully.
Distributed Lock Approach#
For multi-date reservations (e.g., 5-night stay), all dates must be atomically reserved. Use a distributed lock (Redis SETNX or Redlock) keyed on room_type_id to serialize concurrent booking attempts for the same room type.
The lock is held only during the inventory decrement — typically under 50 milliseconds — then released.
Two-Phase Reservation#
- Hold phase — Temporarily reserve inventory for 10-15 minutes while the user completes payment. Decrement
booked_roomsand set a TTL. - Confirm phase — On successful payment, the reservation becomes permanent.
- Release phase — If the hold expires without payment, a background job releases the inventory.
Pricing Engine#
Hotel pricing is far more complex than a static rate card.
Dynamic Pricing Factors#
- Demand-based — Higher occupancy drives higher prices. When a property hits 80% occupancy for a date, prices increase by a configurable multiplier.
- Seasonal — Peak seasons (holidays, local events) have pre-configured rate adjustments.
- Day-of-week — Weekend vs. weekday rates.
- Length of stay — Discounts for longer stays (e.g., 7+ nights gets 15% off).
- Competitive — Scrape or ingest competitor rates to stay competitive.
- Last-minute — Prices may drop as the check-in date approaches if occupancy is low.
Pricing Computation#
Prices are pre-computed nightly by a batch job and stored in a rate table:
rate_calendar (
room_type_id UUID,
date DATE,
computed_rate DECIMAL,
currency VARCHAR(3),
last_updated TIMESTAMP
)
Real-time adjustments (flash sales, manual overrides) are applied as overlays on top of pre-computed rates.
Reservation Flow#
The end-to-end booking flow:
- Search — User finds a property and selects dates.
- Room selection — User picks a room type and rate plan.
- Hold inventory — System places a temporary hold.
- Guest details — User enters name, contact, special requests.
- Payment — User provides payment information; system authorizes (not captures) the charge.
- Confirmation — On successful auth, inventory hold becomes permanent, confirmation email is sent.
- Capture — Payment is captured closer to check-in date (or immediately, depending on policy).
Reservation States#
PENDING -> HELD -> CONFIRMED -> CHECKED_IN -> COMPLETED
With branches: HELD -> EXPIRED, CONFIRMED -> CANCELLED, CONFIRMED -> NO_SHOW
Payment Integration#
Integrate with Stripe, Adyen, or similar gateways. Key patterns:
- Authorize at booking, capture at check-in — Reduces refund friction for cancellations.
- Idempotency keys — Every payment request uses an idempotency key to prevent duplicate charges on retries.
- Multi-currency — Store prices in the property's local currency; convert at display time using daily exchange rates.
- PCI compliance — Never store raw card data. Use tokenization via the payment gateway.
Cancellation Policies#
Hotels define cancellation policies per rate plan:
- Free cancellation — Full refund if cancelled more than 24-48 hours before check-in.
- Non-refundable — No refund; typically offered at a discounted rate.
- Partial refund — First night charged, remaining nights refunded.
The system enforces policies automatically:
cancellation_policy (
rate_plan_id UUID,
deadline_hours INT, -- hours before check-in
penalty_type ENUM('none', 'first_night', 'full_stay', 'percentage'),
penalty_value DECIMAL
)
When a cancellation is processed, the system calculates the refund amount, initiates the refund via the payment gateway, and releases the inventory.
Review System#
Post-checkout, guests receive a review prompt. Reviews include:
- Overall rating (1-5 stars).
- Category ratings — Cleanliness, location, service, value.
- Text review — Free-form feedback.
- Photos — Optional image uploads.
Moderation Pipeline#
- Automated screening — Flag reviews with profanity or spam signals.
- Verified stay check — Only guests with a completed reservation can leave reviews.
- Hotel response — Properties can respond publicly to reviews.
Aggregation#
Property ratings are pre-computed and updated asynchronously. A weighted average gives more weight to recent reviews. The aggregated score is denormalized into the search index for fast retrieval.
Scaling for Peak Seasons#
Peak periods (New Year's Eve in Times Square, summer in the Mediterranean) can see 10x normal traffic.
Read Path Scaling#
- Elasticsearch for search with horizontal scaling — add read replicas during peak.
- CDN caching for property pages and images.
- Pre-computed availability snapshots refreshed every few minutes rather than querying live inventory on every search.
Write Path Scaling#
- Partition inventory by property — Each property's inventory is independent, enabling horizontal partitioning.
- Queue-based booking — During extreme spikes, booking requests enter a queue and are processed serially per room type, preventing lock contention.
- Auto-scaling — Reservation and payment services scale horizontally behind a load balancer.
Graceful Degradation#
- Stale search results — Show cached results with a "prices may have changed" disclaimer.
- Waitlists — When a property sells out, offer to notify users if a room becomes available.
- Rate limiting — Protect inventory writes from bot traffic and scraping.
Key Design Trade-offs#
| Decision | Trade-off |
|---|---|
| Optimistic locking vs. distributed locks | Simpler for single-date bookings vs. needed for multi-date atomicity |
| Pre-computed pricing vs. real-time | Faster reads but potential staleness vs. always accurate but slower |
| Authorize vs. capture at booking | Better UX for cancellations vs. guaranteed revenue |
| Overbooking margin | Higher revenue vs. risk of walking guests |
| Eventual consistency for search | Better performance vs. showing sold-out rooms briefly |
Conclusion#
A hotel booking system is a study in balancing consistency and performance. The inventory subsystem demands strong consistency to prevent double-bookings, while the search subsystem thrives on eventual consistency and aggressive caching. Dynamic pricing, cancellation policies, and peak-season scaling add layers of complexity that make this a compelling system design problem.
The key insight is separating the read path (search) from the write path (booking) — optimizing each independently while keeping them loosely coupled through event-driven updates.
Ready to practice system design problems like this with AI-powered feedback? Try it at codelit.io.
This is article #201 in the Codelit system design series.
Try it on Codelit
Chaos Mode
Simulate node failures and watch cascading impact across your architecture
Related articles
Try these templates
Uber Real-Time Location System
Handles 5M+ GPS pings per second using H3 hexagonal geospatial indexing.
6 componentsE-Commerce Checkout System
Production checkout flow with Stripe payments, inventory management, and fraud detection.
11 componentsAirbnb-like Booking Platform
Property rental marketplace with search, booking, payments, and reviews.
10 componentsBuild this architecture
Generate an interactive architecture for Hotel Booking System Design in seconds.
Try it in Codelit →
Comments