Designing Airbnb
A lodging marketplace — search by location and date availability, and the booking flow that must never double-book a property.
The problem
Design Airbnb/Booking.com: hosts list properties; guests search by location and dates, see available listings, and book — with the hard guarantee that a property is never double-booked for overlapping dates. The crux is availability search + a consistent booking transaction.
Step 1 — Requirements
Functional: hosts create listings (location, photos, price, calendar); guests search by location + date range + filters (guests, price, amenities) showing only available listings; book (reserve dates); reviews; messaging.
Non-functional: low-latency search, strong consistency for bookings (no double-booking — money + real-world resource), read-heavy browse, available, scalable.
Step 2 — Search (geo + availability)
Two filters combine:
- Location — geospatial index (geohash/quadtree, reuse Yelp) for “listings in this area / map viewport.”
- Availability for the date range — a listing is a candidate only if its calendar is free for all requested nights.
- Plus filters (price, guests, amenities) and ranking (relevance, quality, price).
Availability search is the twist: you’re querying “free across a date range,” not a point.
Step 3 — Modeling availability
Represent each listing’s calendar so “are nights D1..D2 all free?” is fast:
- Per-night records — a row per (listing, date) with a status; a range query checks all nights are free. Simple, but many rows.
- Booked-ranges — store booked intervals; availability = the requested range overlaps no booked interval (interval overlap check).
Search uses a denormalized availability index (e.g. Elasticsearch with date ranges, or precomputed availability) for fast filtering; the source of truth calendar lives in a transactional store for booking.
Step 4 — Booking without double-booking (the core)
Two guests may try the same dates at once. Prevent double-booking with a consistent, atomic reservation:
- Transaction / unique constraint — within a DB transaction, check the nights are free and insert the booking; a unique constraint on (listing, date) (or an exclusion constraint on overlapping ranges) makes the DB reject a conflicting second booking.
- Pessimistic lock — lock the listing’s calendar rows for the dates while booking.
- Hold + confirm — place a short hold (lease) on the dates during checkout, then confirm on payment; the hold expires if abandoned (so dates aren’t stuck).
This must be strongly consistent (CP) — unlike search, which can be eventually consistent.
Step 5 — The booking flow
search (geo + availability index) → listing page (live availability check)
→ start booking: place hold (lease) on dates → take payment
→ confirm: transactional insert (unique/exclusion constraint) → booking created
(payment fails / hold expires → release dates)
A saga-like flow (hold → pay → confirm with compensation) coordinates payment and the reservation.
Step 6 — Architecture
search → geo index + availability index (denormalized, eventually consistent)
listing → details (cached) + live availability (source of truth)
booking → reservation service (transactional, unique/exclusion constraint) ⇄ payment
host calendar updates → propagate to the availability search index (async)
Trade-offs to raise
- Search index eventually consistent (fast, may briefly show a just-booked listing) vs booking strongly consistent (authoritative). Split them — re-check availability at booking time.
- Per-night rows (simple range queries, many rows) vs interval ranges (compact, overlap logic).
- Hold/lease (good UX, dates briefly reserved) vs book-on-click.
The interview cue
“Search combines a geo index with an availability index over date ranges (eventually consistent, re-checked at booking); booking is a strongly consistent transaction with a unique/exclusion constraint on (listing, dates) — plus a hold + confirm flow with payment — so it can’t double-book. Calendar updates propagate to the search index async.” Availability search + a CP booking transaction (no double-booking) is the distinguishing answer; implementation next.