SYSTEM_DESIGN
System Design: Airbnb
Design Airbnb's home rental marketplace covering listing search, booking calendar management, payment processing, and review systems at global scale.
Requirements
Functional Requirements:
- Hosts list properties with photos, descriptions, amenities, pricing, and availability calendar
- Guests search for listings by location, dates, guests, price range, and amenities
- Booking flow: request or instant-book with calendar blocking on acceptance
- Messaging between hosts and guests before and during stays
- Reviews for both guests and hosts after checkout
- Dynamic pricing suggestions for hosts based on local demand
Non-Functional Requirements:
- Search returns results in under 500ms at the 95th percentile
- Calendar availability must be strongly consistent — double bookings are catastrophic
- Support 100 million listings worldwide; 150 million active users
- High availability for the booking path: 99.99% uptime
- PCI-DSS compliance for payment processing
Scale Estimation
100 million listings; 150 million users; 14 million trips booked/year = ~38,000/day = ~440 bookings/minute. Search load is the heaviest: 500 million searches/year = ~1,600 searches/second average, ~10,000/second peak (summer travel season). Each search has multiple filters (location, dates, guests, price) requiring an availability check — naively querying each listing's calendar is infeasible at this scale. Photo storage: 100 million listings × 20 photos × 2 MB = ~4 PB.
High-Level Architecture
Airbnb's platform centers on three core flows: the Supply Side (host listing management), the Search & Discovery Side (guest search experience), and the Transaction Side (booking, payment, messaging).
The Search Service is the most performance-critical component. It uses Elasticsearch as the primary search index, with listing documents containing pre-computed availability windows ("available for these dates" precomputed by the Calendar Service on each calendar update). When a guest searches for Paris for 3 nights in July, the query hits Elasticsearch which filters by geobounding box, date availability window, and guest capacity, returning ranked results in under 100ms. The Calendar Service independently maintains a strongly consistent availability store in MySQL with row-level locking for booking transactions.
The Booking Service orchestrates the reservation flow: check availability (MySQL SELECT FOR UPDATE), create a hold (TTL 10 minutes for request-to-book, immediate for instant-book), charge the payment (Stripe/Braintree), and on payment success, create the confirmed booking and update the calendar. This is a distributed transaction managed with a saga pattern — if payment fails, the calendar hold is released.
Core Components
Search & Ranking Engine
Listings are indexed in Elasticsearch with geo_point for location filtering and date availability stored as a series of available date ranges. Text search (amenities, description) uses BM25 with a custom boost for Superhost status, review score, and price competitiveness. Personalization: a separate ML ranking model (trained on user click and booking history) re-ranks Elasticsearch results for logged-in users via a Learning-to-Rank layer. Search results are cached in Redis by (geohash, date_range, guest_count, filters) with a 5-minute TTL.
Calendar & Availability Service
Each listing's calendar is a set of blocked date ranges stored in MySQL: (listing_id, block_start, block_end, block_reason {BOOKING, HOST_BLOCK, PLATFORM_HOLD}). Availability check for a given date range is a gap query. Booking creates an atomic insert with a uniqueness constraint (no overlapping ranges for the same listing_id) enforced by a compound index and a stored procedure. MySQL is chosen over NoSQL for this component specifically because of ACID guarantee requirements — a distributed NoSQL store cannot safely enforce the non-overlapping invariant.
Payment & Payout System
Airbnb holds guest payments in escrow for 24 hours after check-in before releasing to hosts (protecting against misrepresentation). The Payment Service integrates with Stripe to charge guests and with Stripe Connect for host payouts. A ledger table in MySQL tracks every financial event: GUEST_CHARGED, PLATFORM_FEE_TAKEN, HOST_PAYOUT_INITIATED, REFUND_ISSUED. Double-entry bookkeeping ensures ledger balance is always zero. Payouts to hosts in 220+ countries require multi-currency support and international banking integration.
Database Design
Listings in PostgreSQL (sharded by listing_id): (listing_id, host_id, title, description, location_geom, price_per_night, max_guests, amenities JSONB, status). A PostGIS spatial index serves location-based queries. Listing photos in S3 with CloudFront CDN; photo URLs stored in PostgreSQL. Calendar in MySQL (per-region sharding by listing_id hash) for strong consistency. Bookings in PostgreSQL with a write-ahead log replica for analytics. Messages in Cassandra (partition key = conversation_id, clustering key = sent_at DESC) for scalable messaging history. Reviews in PostgreSQL with a materialized view for listing average ratings.
API Design
- GET /v1/listings/search?location={}&checkin={}&checkout={}&guests={} — Full-text + geo + availability search; returns paginated listing cards with prices and availability
- POST /v1/bookings — Guest submits booking request or instant-book; accepts listing_id, check-in/out dates, guest count, payment_method_id; returns booking_id or REQUEST status
- PUT /v1/listings/{listing_id}/calendar — Host updates blocked dates or availability; triggers Elasticsearch index update for affected date ranges
- POST /v1/reviews — Post-checkout review submission; only available within 14 days of checkout; triggers host/guest notification
Scaling & Bottlenecks
Search is the dominant bottleneck: 10,000 queries/second peak hitting Elasticsearch. The index is distributed across 10 shards × 2 replicas; each shard handles ~500 queries/second (Elasticsearch sweet spot). For peak loads, a Redis cache layer (5-minute TTL, keyed by hashed search parameters) handles ~70% of traffic as repeated searches for popular destinations during high season.
Calendar writes are the consistency bottleneck. MySQL is vertically scaled (high-memory instances for in-memory InnoDB buffer pool) and sharded by listing_id. Cross-shard queries (rare in the calendar use case) are avoided by design. The booking saga includes a compensation transaction (calendar hold release) that fires automatically via a scheduled job if payment confirmation doesn't arrive within 15 minutes.
Key Trade-offs
- Elasticsearch availability vs. MySQL consistency — search index may briefly show a listing as available while a booking is in progress (lag of <30 seconds); the Calendar Service performs a final definitive availability check at booking time to prevent double booking
- Instant Book vs. Request-to-Book — instant book is better for conversion (no waiting) but requires higher host trust; Airbnb defaults to instant book for hosts with good standing
- Escrow hold period — 24-hour hold protects guests but delays host payouts; extending it improves protection but harms host cash flow
- Review system timing — both parties submit reviews before either sees the other's; this "blind review" prevents retaliation but requires a 14-day window that most users don't use, creating a selection bias toward extreme experiences
GO DEEPER
Master this topic in our 12-week cohort
Our Advanced System Design cohort covers this and 11 other deep-dive topics with live sessions, assignments, and expert feedback.