How to Design Airbnb — System Design Interview Question & Answer



1. Interview Question
Design a system like Airbnb where users can search for properties, view listings, check availability, make reservations, pay for bookings, and manage their trips.
Assume the system needs to support:
- Guests searching for properties
- Hosts creating and managing listings
- Location/date/guest-based search
- Real-time availability
- Reservation and cancellation
- Payments
- Reviews and ratings
- Notifications
- High availability and global scale
2. Clarify Requirements
Before drawing architecture, clarify the scope.
Functional Requirements
Guest
-
Register/login
-
Search properties
-
Filter by:
- Location
- Check-in/check-out
- Number of guests
- Price
- Amenities
- Rating
-
View property details
-
Check availability
-
Reserve a property
-
Pay
-
Cancel reservation
-
Review property
Host
- Create listing
- Upload photos
- Set price
- Define availability
- Block/unblock dates
- Accept/manage reservations
- Receive payments
Platform
- Notifications
- Fraud detection
- Reviews
- Pricing
- Search ranking
- Analytics
3. Non-Functional Requirements
For a system like Airbnb, these are particularly important.
| Requirement | Target |
|---|---|
| Availability | 99.99%+ |
| Search latency | < 200–300 ms |
| Booking latency | < 2–5 sec |
| Payment correctness | Strong consistency |
| Search | Highly scalable |
| Booking | No double booking |
| Images | Highly durable |
| Global access | Multi-region |
| Fault tolerance | Required |
The most important distinction is:
Search can be eventually consistent. Booking cannot.
A slightly stale search result is annoying.
A double booking is a business disaster.
4. High-Level Architecture
A good starting architecture:
┌─────────────────────┐
│ Web / Mobile │
└──────────┬──────────┘
│
CDN / WAF
│
API Gateway
│
┌─────────────────────┼─────────────────────┐
│ │ │
User Service Listing Service Search Service
│ │ │
│ │ Elasticsearch
│ │
└──────────────┬──────┴──────────────┐
│ │
Availability Service Pricing Service
│ │
└──────────┬──────────┘
│
Booking Service
│
┌───────────┼───────────┐
│ │ │
Payment Notification Review
Service Service Service
│
Payment Provider
│
┌───────────────────┼────────────────────┐
│ │ │
PostgreSQL Redis Kafka
│ │
└──────────────────────────────────────┘
5. Core Microservices
Don’t create dozens of services immediately.
Start with the important bounded contexts.
User Service
Responsible for:
User
Profile
Authentication
Identity
Listing Service
Responsible for:
Property
Listing
Amenities
Photos
House rules
Host information
Example:
Listing
---------
listing_id
host_id
title
description
property_type
address
latitude
longitude
max_guests
base_price
currency
status
created_at
Search Service
Responsible for:
Location search
Date search
Filters
Sorting
Ranking
This is where Elasticsearch/OpenSearch becomes useful.
Availability Service
Responsible for:
Is property available?
What dates are blocked?
What dates are booked?
This is one of the most important components.
Booking Service
Responsible for:
Create reservation
Cancel reservation
Modify reservation
Booking state
Idempotency
Payment Service
Responsible for:
Payment authorization
Capture
Refund
Payment status
Host payout
Review Service
Responsible for:
Guest reviews
Host reviews
Ratings
Moderation
Notification Service
Handles:
Email
SMS
Push notification
In-app notification
Kafka is a good fit for asynchronous events.
6. Database Design
A relational database is a strong choice for the transactional core.
For example:
PostgreSQL
users
-----
id
name
email
created_at
listings
--------
id
host_id
title
description
latitude
longitude
price
currency
max_guests
created_at
reservations
------------
id
listing_id
guest_id
check_in
check_out
status
total_price
payment_id
created_at
availability
------------
listing_id
date
status
price
payments
--------
id
reservation_id
amount
currency
status
provider_reference
created_at
reviews
-------
id
reservation_id
listing_id
guest_id
rating
comment
created_at
7. The Most Important Problem: Search
Suppose Airbnb has:
10 million listings
A user searches:
London
Aug 20–25
2 guests
£100–£200/night
You don’t want to scan the relational database:
SELECT *
FROM listings
WHERE city = 'London'
AND price BETWEEN 100 AND 200;
At Airbnb scale, that becomes problematic.
Instead:
Search Request
│
▼
Search Service
│
▼
Elasticsearch
│
┌──────────┴──────────┐
│ │
Geo filter Price filter
│ │
└──────────┬──────────┘
▼
Candidate Listings
│
▼
Availability Check
│
▼
Ranking
│
▼
Results
8. Why Elasticsearch?
Search requires multiple dimensions:
Location
Price
Guests
Amenities
Property type
Rating
Popularity
Availability
Elasticsearch/OpenSearch provides:
- Geo queries
- Full-text search
- Filtering
- Faceting
- Ranking
- Distributed indexing
For example:
geo_distance
price range
guest count
amenities
rating
9. Geo Search
A user searches:
Properties within 5 km of Central London.
Store:
latitude
longitude
Then Elasticsearch can perform:
geo_distance < 5km
Conceptually:
London
●
┌───────────┐
│ 5 km │
│ ● │
│ │
└───────────┘
10. Availability Is the Hard Part
This is where many candidates make mistakes.
Suppose:
Listing A
Aug 10 ───────── Aug 20
available
Guest 1 wants:
Aug 15 → Aug 20
Guest 2 simultaneously wants:
Aug 18 → Aug 25
Both requests could see:
AVAILABLE
If we don’t synchronize booking:
Guest 1 ────────┐
├── BOOK
Guest 2 ────────┘
We get:
Double booking
11. Preventing Double Booking
The booking operation needs a concurrency-control mechanism.
One approach is a database transaction with a uniqueness constraint / exclusion constraint over the reserved date range.
Conceptually:
BEGIN TRANSACTION
Check availability
Lock inventory
Create reservation
Update availability
COMMIT
For example:
BEGIN;
SELECT *
FROM availability
WHERE listing_id = ?
AND date >= ?
AND date < ?
FOR UPDATE;
-- verify all dates are available
INSERT INTO reservations (...);
UPDATE availability
SET status = 'BOOKED'
WHERE listing_id = ?
AND date >= ?
AND date < ?;
COMMIT;
The important point isn’t the exact SQL.
It’s:
The final booking decision must happen against a strongly consistent source of truth.
12. Alternative: Inventory Lock
Another approach is a short-lived distributed lock:
Redis
LOCK listing:123:2026-08-20
Then:
Request A
│
▼
Acquire lock
│
▼
Check availability
│
▼
Create booking
│
▼
Release lock
Request B:
Acquire lock
│
X
LOCKED
However:
Redis locks should not be the only correctness mechanism.
The database should still enforce the final invariant.
13. Booking State Machine
Don’t model booking as simply:
BOOKED / NOT BOOKED
A better model:
┌───────────┐
│ PENDING │
└─────┬─────┘
│
payment OK
│
▼
┌───────────┐
│ CONFIRMED │
└─────┬─────┘
│
check-in
│
▼
┌───────────┐
│ COMPLETED │
└───────────┘
PENDING ──────► CANCELLED
CONFIRMED ────► CANCELLED
This makes retries and failures much easier to handle.
14. Payment Architecture
Never assume:
Booking created
↓
Payment succeeded
Payment providers can timeout.
The request can be retried.
The client can disconnect.
Therefore:
Booking Service
│
▼
Payment Service
│
▼
Payment Provider
│
▼
Webhook
│
▼
Payment Service
│
▼
Booking CONFIRMED
The webhook becomes an important source of payment state.
15. Idempotency
This is another major interview topic.
Imagine the user clicks:
Book Now
twice.
Or the mobile network retries the request.
Without idempotency:
Request 1 → Booking #123
Request 2 → Booking #124
Bad.
Instead:
POST /reservations
Idempotency-Key: 8f73...
The Booking Service stores:
idempotency_key
reservation_id
response
Repeated requests return the original result.
16. Event-Driven Architecture
After booking:
Booking Confirmed
│
▼
Kafka
│
┌─────┼─────────────┐
│ │ │
▼ ▼ ▼
Email Analytics Host Notification
│
▼
Push Notification
The Booking Service shouldn’t synchronously call:
Email
SMS
Analytics
Recommendation
for every operation.
That increases latency and failure coupling.
Instead:
Booking → Event → Kafka
Consumers process the event independently.
17. Caching
Use Redis for frequently accessed data.
Good candidates:
Listing details
Popular destinations
Search metadata
User sessions
Pricing information
Availability cache
Example:
GET /listing/123
│
▼
Redis
│
Cache Hit?
/ \
Yes No
│ │
▼ ▼
Return PostgreSQL
│
▼
Redis
But be careful:
Don’t trust stale cache data for the final booking decision.
18. Image Storage
Airbnb has huge amounts of photos.
Don’t store images in PostgreSQL.
Use object storage:
Client
│
▼
Object Storage
│
▼
CDN
For example:
S3
↓
CloudFront
↓
User
The database stores:
image_id
listing_id
image_url
metadata
not the image itself.
19. Search Index Synchronization
Suppose a host changes:
Price: £150 → £180
The relational database changes first:
PostgreSQL
│
▼
ListingUpdated event
│
▼
Kafka
│
▼
Search Index
This creates eventual consistency:
PostgreSQL = £180
Elasticsearch = £150
temporarily.
That’s acceptable for search.
But before booking:
Search
↓
Availability
↓
Pricing
↓
Booking
The transactional services verify the current state.
20. Handling Millions of Search Requests
Search traffic is usually much higher than booking traffic.
For example:
Search: 100,000 req/sec
Listing view: 20,000 req/sec
Booking: 500 req/sec
Therefore:
API Gateway
│
┌──────────┴──────────┐
│ │
Search Booking
│ │
┌─────┴─────┐ ┌────┴────┐
│ │ │ │ │
ES1 ES2 ES3 DB1 DB2
Search scales horizontally.
21. Read vs Write Path
This is a useful interview distinction.
Search Read Path
User
↓
API Gateway
↓
Search Service
↓
Elasticsearch
↓
Redis
↓
Response
Optimized for:
High throughput + low latency
Booking Write Path
User
↓
API Gateway
↓
Booking Service
↓
Availability DB
↓
Payment Service
↓
Payment Provider
↓
Booking DB
↓
Kafka
↓
Notifications
Optimized for:
Correctness + consistency
22. Scaling the Database
Start with:
PostgreSQL Primary
│
┌─────┼──────┐
▼ ▼ ▼
Read Read Read
Replica Replica Replica
Reads go to replicas.
Writes go to primary.
But booking operations requiring strong consistency should use the appropriate primary/transactional path.
23. Partitioning
At very large scale, partition reservation/availability data.
Possible partition key:
listing_id
or:
region
For example:
Shard 1 → Europe
Shard 2 → North America
Shard 3 → Asia
Shard 4 → Australia
However, geographic partitioning isn’t always sufficient because users can search globally.
A common approach is to separate:
Search infrastructure
from:
Transactional booking infrastructure
and scale each independently.
24. Multi-Region Architecture
For a global Airbnb-like system:
Global DNS
│
┌─────────────┼─────────────┐
│ │ │
Europe North America Asia
│ │ │
Region A Region B Region C
Each region can have:
API Gateway
Services
Cache
Search cluster
Database
Kafka
The difficult part is global booking consistency.
You don’t want:
Europe → books listing 123
US → books listing 123
at exactly the same time.
Therefore, inventory ownership / partitioning and a single authoritative write path for a listing become important.
25. Failure Handling
Consider:
Payment succeeds
↓
Booking service crashes
What happens?
You don’t want:
Customer charged
BUT
Reservation missing
Use:
- Idempotency
- Durable state
- Transactional state transitions
- Payment webhooks
- Retry queues
- Reconciliation jobs
For example:
Payment Provider
│
▼
Webhook
│
▼
Payment Service
│
▼
Reconciliation
│
▼
Booking Service
A periodic reconciliation job can detect:
Payment = SUCCESS
Booking = PENDING
and repair the state.
26. Cancellation
Cancellation isn’t simply:
DELETE reservation
Instead:
CONFIRMED
│
▼
CANCELLATION_REQUESTED
│
▼
REFUND_PROCESSING
│
▼
CANCELLED
Then:
availability → AVAILABLE
and:
payment → REFUNDED
depending on the cancellation policy.
27. Reviews
A review should generally be allowed only when:
Reservation = COMPLETED
And enforce:
One review per reservation
Database constraint:
UNIQUE(reservation_id, reviewer_id)
This prevents duplicate reviews.
28. Security
Important security considerations:
Authentication
OAuth2 / OIDC
JWT / session
MFA
Authorization
Host:
Can modify own listing
Guest:
Can modify own reservation
Admin:
Can moderate listings/reviews
Never trust:
host_id
user_id
price
from the client.
29. Observability
At Airbnb scale, observability is critical.
Use:
Metrics
Logs
Distributed tracing
Alerts
Track:
Search latency
Booking success rate
Payment failure rate
Double-booking attempts
Kafka lag
Database latency
Cache hit ratio
Search index freshness
A useful distributed trace:
Request
│
├── API Gateway
│
├── Search
│ └── Elasticsearch
│
├── Availability
│ └── PostgreSQL
│
├── Booking
│
└── Payment
└── Payment Provider
30. Complete Architecture
Putting everything together:
┌─────────────────┐
│ Web / Mobile │
└────────┬────────┘
│
CDN / WAF
│
API Gateway
│
┌─────────────────────────┼────────────────────────┐
│ │ │
▼ ▼ ▼
User Service Search Service Listing Service
│ │ │
│ ┌──────┴──────┐ │
│ │ │ │
│ Elasticsearch Redis │
│ │
└──────────────────────────┬─────────────────────────┘
│
Availability
│
▼
Booking Service
│
┌───────────┼───────────┐
│ │ │
▼ ▼ ▼
PostgreSQL Payment Pricing
│
▼
Payment Provider
│
▼
Kafka
│
┌──────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
Notification Analytics Review
Service Service Service
│
┌─────┴─────┐
▼ ▼
Email Push
Listings / Images
│
▼
Object Storage
│
▼
CDN
31. Key Design Decisions
In the interview, explicitly explain these trade-offs.
| Problem | Design |
|---|---|
| Search | Elasticsearch/OpenSearch |
| Transactional data | PostgreSQL |
| Cache | Redis |
| Events | Kafka |
| Images | Object Storage |
| Image delivery | CDN |
| Search scalability | Horizontal scaling |
| Double booking | DB transaction + constraints |
| Duplicate requests | Idempotency keys |
| Payment consistency | Webhooks + reconciliation |
| Notifications | Async events |
| Global scale | Multi-region |
| Availability | Strong consistency |
| Search freshness | Eventual consistency |
32. What Interviewers Really Want to Hear
For a senior/lead engineer, don’t spend 30 minutes drawing boxes.
Focus on the difficult problems.
The five most important areas:
1. Search
Geo + filters + ranking
→ Elasticsearch
2. Availability
No double booking
→ transactional source of truth
3. Booking
Idempotency
+ state machine
+ concurrency control
4. Payment
Async payment confirmation
+ webhook
+ reconciliation
5. Scale
Search → horizontally scalable
Booking → strongly consistent
Notifications → event driven
33. A Strong 5-Minute Interview Answer
If the interviewer asks you to summarize the design, you can say:
“I would separate Airbnb into a read-heavy search architecture and a strongly consistent transactional booking architecture.
For search, I would use Elasticsearch/OpenSearch to support geo queries, filtering, availability candidates, and ranking. Listing data would originate from a relational database and be asynchronously indexed through Kafka.
For booking, I would use a relational database as the source of truth. The booking operation would run inside a transaction and use concurrency control and database constraints to guarantee that two users cannot reserve the same inventory.
I would make booking APIs idempotent because clients and payment providers can retry requests. Payments would be handled through a payment service, with asynchronous webhooks used to confirm payment state.
After a booking is confirmed, the Booking Service would publish an event to Kafka. Notification, analytics, and other downstream services would consume the event independently.
Redis would be used for caching frequently accessed data, while property images would be stored in object storage and served through a CDN.
At global scale, I would deploy services across multiple regions, but I would ensure that each listing has an authoritative transactional path so that concurrent bookings cannot result in double booking.
The key architectural principle is that search can tolerate eventual consistency, while booking and payment require much stronger consistency and correctness.”
34. Follow-Up Questions You Should Expect
An interviewer will likely drill into these:
Easy
- Why use Elasticsearch?
- Why PostgreSQL?
- Why Redis?
- Why Kafka?
- How would you store images?
- How would you implement search by location?
Medium
- How do you prevent double booking?
- How do you handle concurrent bookings?
- How do you handle payment failures?
- How do you implement cancellation?
- How do you make booking idempotent?
- How do you synchronize Elasticsearch with PostgreSQL?
- How would you cache availability?
Senior/Lead
- How would you design multi-region booking?
- How would you handle a region failure?
- How would you partition reservation data?
- What happens if payment succeeds but booking fails?
- What happens if Kafka is unavailable?
- How do you recover from inconsistent payment/booking states?
- How would you support 100K+ searches/sec?
- How would you prevent a hot listing from becoming a bottleneck?
- How would you design pricing for millions of listings?
- How would you implement search ranking?
- How would you detect fraudulent bookings?
- How would you guarantee exactly-once business effects?
The Core Principle to Remember
The best Airbnb system-design answer isn’t about drawing the most microservices.
It’s about recognizing that different parts of the system have fundamentally different consistency requirements:
Airbnb
│
┌────────────┴────────────┐
│ │
SEARCH BOOKING
│ │
High throughput High correctness
Low latency Strong consistency
Eventual consistency Transactions
Elasticsearch PostgreSQL
Redis Idempotency
Concurrency control
Payment
That’s the architectural insight that usually separates a mid-level answer from a strong senior/lead-level system-design answer.