Revision sheet

Design hotel reservation.

The six things worth holding in your head the night before. Everything else is on the full page.

The opening move — minute one

“A hotel sells room-nights, not rooms — a count per room type per night, so a three-night booking must reserve three rows atomically. And unlike e-commerce, I’m allowed to oversell on purpose: no-shows run ~8%, so the ceiling is physical × (1 + overbook rate), with a walk policy for the night the statistics lose. Search is cached and may lie; the book path never does. At ~3M bookings a day — ~35 a second — the database is boring; the policy is the design.”

The booking state machine

PENDING → CONFIRMED → CHECKED_IN → CHECKED_OUT
CANCELLED (hold expired or guest cancelled — the window is evaluated property-local) · NO_SHOW (night audit: charge the fee, release the nights, feed the forecast) · WALKED (everyone showed — partner room + transport, logged as the policy’s cost)

Must-haves

  1. Models inventory as counts per (room type, night) — no physical-room rows, no date-range arithmetic on the booking path — and assigns room numbers at check-in.
  2. Reserves a multi-night stay atomically: conditional updates against the sellable ceiling in one transaction, date-ordered locking, rowcount == N or rollback — and names the TOCTOU race in check-then-insert.
  3. Treats overbooking as bounded policy: sellable = physical × (1 + overbook_rate) as data, reserved ≤ sellable as invariant, a walk policy with named compensation — and zeroes the rate on compression nights.
  4. Splits search from book — cached, fan-out, allowed-to-lie search against a strongly consistent book path — and does the arithmetic (~3M/day ≈ ~35 TPS) that keeps one ACID database the right answer.

Red flags

  • Read-then-write availability anywhere on the book path, or a multi-night stay that can partially book.
  • Refusing the overbooking requirement (“just never oversell”) or implementing it without bounds — both miss that it’s a tuned, priced policy.
  • Charging cards at booking on guarantee rates, or evaluating cancellation windows in UTC.

The 7 trap claims — each one is wrong

  1. “model each physical room, and book room 204”
  2. “never sell more rooms than the hotel has”
  3. “check that the nights are free, then insert the booking”
  4. “charge the card when the booking is made”
  5. “store availability as date ranges per booking”
  6. “make search strongly consistent so it never lies”
  7. “a no-show just frees up the room”

The L4 lines — what depth sounds like

Room-Night Inventory & Multi-Night Atomicity

Adds date-ordered locking against deadlock between overlapping stays, reasons about isolation (why read-committed plus conditional updates suffices), and prices false “unavailable” against oversell under retry storms

Overbooking Policy & Walk Handling

Closes the control loop: no-show actuals and walk costs feed a per-(property, night) forecast, compression nights are detected from sellout velocity, and the walk budget is an explicit revenue trade

Booking Lifecycle & Holds Without Money

Handles the seams: bounded hold extension during the guarantee attach, cancel-vs-check-in races as conditional row updates, no-show fees against the token, and a time-zone-correct night audit as the lifecycle’s clock

Search / Book Split & Hot Nights

Handles the compression night end to end: local row-contention analysis (why row locks suffice at ~500/s), demand shaping at the edge, overbook-rate zeroing, and cache-vs-ledger drift reconciliation