ayushsalampuriya.xyz Revise

System Design · Design Question

Design a Booking System

Hotels / tickets / appointments: inventory, holds, payments, and how to avoid overselling under concurrency.

1. Requirements

Pick a concrete domain in interview: "hotel room nights" Ask: unique rooms vs pooled room-type inventory? overbooking %?

2. API

GET /v1/availability?hotelId=&checkIn=&checkOut=&guests= POST /v1/holds { hotelId, roomTypeId, checkIn, checkOut, customerId } → { holdId, expiresAt, price } POST /v1/bookings { holdId, paymentMethod, Idempotency-Key } → { bookingId, status } POST /v1/bookings/{id}/cancel

3. Data model

hotels, room_types(room_type_id, hotel_id, capacity_attrs) inventory(room_type_id, date, total, reserved, held) -- reserved = confirmed; held = soft lock holds(hold_id, room_type_id, dates, expires_at, status) bookings(booking_id, hold_id, user_id, status, amount) UNIQUE constraints / TX protect inventory rows

For assigned seats/rooms, model each unit; for hotels often count-based inventory per room type per night.

4. High-level design

Client → API Gateway → Search Service (read replicas / cache) → Booking Service → Inventory DB (strong consistency path) → Payment Service → Notification queue Hold Expiry Worker releases expired holds

5. Concurrency: do not oversell

-- In one DB transaction: SELECT total, reserved, held FROM inventory WHERE room_type_id=? AND date IN (...) FOR UPDATE IF any day reserved+held+need > total → abort UPDATE inventory SET held = held+need ... INSERT hold expires_at = now()+10min COMMIT

6. Hold → pay → confirm saga

1) Create hold (inventory held++) 2) Charge payment (idempotent) 3) On success: held-- , reserved++ ; booking confirmed 4) On fail/expiry: held-- ; hold cancelled 5) Payment success but confirm crash → reconcile job uses payment id / hold id

7. Search scaling

8. Overbooking (optional product)

Airlines intentionally overbook statistically. If required, raise total effective capacity and define compensation workflow — say it explicitly; do not “accidentally” oversell.

9. Scaling writes

10. Edge cases

Quick revision

  • Separate search (cacheable) from hold/book (strongly consistent TX).
  • Hold with TTL; worker releases expiry.
  • Protect inventory with row locks or optimistic versions.
  • Saga: hold → pay → confirm; compensate on failure.
  • Idempotency keys on booking and payment.
  • Shard by hotel; watch hot-date contention.
  • Overbooking only as an explicit policy, not a race bug.