SDSystem design
Start learning free

LESSON 118 OF 140 · PRACTICE PROBLEMS

SYSTEM DESIGN · INTERVIEW WALKTHROUGH

Design Airbnb: System Design Interview Practice

The problem

"Design Airbnb." Hosts rent out their own homes; guests search an area for their dates and number of guests, then book a whole place, often by sending a request the host accepts. The money goes from the guest to the host, with you in between.

This practice problem reuses Design Hotel Booking: a stay is a range of nights, booked every night or none, and search reads a copy while the booking checks the real rows. What's new: each listing is one home, hosts run their own calendars and prices, a request waits up to 24 hours for the host, and you hold the money until the guest arrives. Park reviews and messages.

The numbers

From the interviewer: 5 million listings and about 5,000 searches a second. A search for Paris matches about 50,000 listings before dates are checked, and Ana wants June 12 to 17: 5 nights, since the check-out day isn't one.

  • Rows per search: checking each listing's nights row by row is 50,000 × 5 = 250,000 rows for one search.
  • Rows per second: at 5,000 searches a second, about 1.25 billion row reads a second. In Hotel Booking a few room types per hotel kept this small; here every listing is its own calendar.
  • Calendar size: 5 million listings × 365 nights is about 1.8 billion night rows, about 180 GB at 100 bytes a row: shard it by listing id, so a stay's nights and its transaction stay on one server.

The calendar: a row per listing per night

A hotel counts rooms of a type; a flat is either free or not. So each listing gets one row per night: its status (open, booked or blocked by the host), its price, and the booking that holds it. The listing row keeps what's the same every night (where it is, how many it sleeps, its host and a base price), and the booking row keeps the guest, the dates and the status of the request.

A booking takes each of its nights with one conditional update, status = 'open', all in one transaction, exactly as Hotel Booking did with booked < total. A host blocking a night at the moment a guest books it hits the same row, so only one wins. Many hosts also list on other sites; those calendars usually come in as blocked nights only every few hours, so in between both sites can sell the same night.

Search: a year of bits per listing

GET /search?area=paris&checkin=2026-06-12&checkout=2026-06-17&guests=2
  → 200 [{"listing": "l42", "total": 1000, …}, …]

POST /requests {"listing": "l42", "checkin": "2026-06-12",
                "checkout": "2026-06-17", "guests": 2,
                "idempotency_key": "k9"}
  → 201 {"id": "r9", "answer_by": "2026-06-02T10:00"}

Reading the calendars database for every search is exact but far too slow. An index of open nights rebuilt once a night is cheap but stale all day.

The middle way: the search index keeps each listing's next 365 nights as 365 bits, about 46 bytes, so all 5 million listings take about 230 MB and every index server holds them in memory. A search filters by area and guests, then checks 5 bits per listing. The booking service sends each calendar change to the index, which is a few seconds behind. A listing can show as open just after it went; the booking's conditional update then finds it taken. As in Hotel Booking, the search shows and the booking decides.

Requests: a 24-hour hold

Many hosts approve each guest within 24 hours: Ana's request r9, sent June 1 at 10:00, must be answered by June 2 at 10:00. Left open meanwhile, her nights can go to another guest. Booked at once, with the host free to cancel, they tell Ana she has a place when she doesn't.

So the request holds the 5 nights: each goes from open to held for r9, with an end time, in one conditional update per night, all or none. It's Ticketmaster's hold, for 24 hours instead of 10 minutes. Accepting turns the nights booked; a decline, or no answer in time, frees them, and the search index hears of each change.

Payments: held until check-in

The host accepts on June 1 and Ana's card is charged $1,000, $200 a night. Paid right away, a host who cancels on June 10, or a listing that was never real, already has her money. Charged only at check-in, a card that fails on June 12 leaves the host a booked week and nothing paid.

So charge at acceptance and hold the money until check-in, then release it, say a day after she arrives. The ledger is Payment System's: each movement is two entries that sum to zero, and a nightly payout sends each host's balance to their bank. Say your fee is $100:

movement           from           to             amount
charge, June 1     Ana's card     held for r9    1,000
release, June 13   held for r9    host           900
release, June 13   held for r9    fees           100
payout, June 13    host           host's bank    900

After the payout, the held account and the host's balance are back to zero; a cancel before June 12 refunds from the held account, which still has all $1,000.

Same pattern as Hotel Booking

Nights as rows, a stay as one transaction of conditional updates, search reading a copy while the booking checks the truth, idempotency keys on calls that move nights or money: all of it carries over. What changed: every listing is a one-room hotel run by its own host, which makes the calendar huge and search the hard part.

Summary

  • Scope: whole homes, hosts' calendars and prices, requests, money held.
  • Numbers: 250,000 rows a search, row by row: too many.
  • Calendar: a row per listing per night, with status and price.
  • Search: 365 bits a listing in the index, seconds old; the booking decides.
  • Requests: the nights held 24 hours for the host's answer.
  • Payments: charged at acceptance, held until check-in, then paid out.
Keep going with system designInteractive lessons from the building blocks to Twitter, Uber and payments, the way interviews ask. Free to start.
Start learning free