The Fundamental Booking Problem
At its heart, a booking system must guarantee:
One user action results in at most one successful booking, without overselling or double-charging, even under retries, crashes, or race conditions.
This is deceptively hard because:
- Multiple users may attempt to book the same inventory simultaneously.
- Clients and gateways retry requests.
- Payments and external calls may partially succeed.
- The system must stay available during spikes and failures.
1. Idempotency: “Do This Once, No Matter How Many Times I Ask”
Why idempotency is critical
In booking systems, retries are normal, not exceptional:
- Mobile clients retry on timeouts.
- Load balancers retry on 5xx.
- Payment providers resend callbacks.
Without idempotency:
- Users get charged twice.
- Inventory is reserved multiple times.
- Data corruption spreads downstream.
Core idempotency patterns
Client-generated idempotency key
- Every booking attempt includes a
request_id. - The backend stores
(request_id → result)durably. - Replays return the original result.
Entity-scoped idempotency
- Booking creation is idempotent by
(user_id, inventory_id, request_id). - Payment confirmation is idempotent by
(payment_provider_event_id).
State-aware idempotency
- State transitions are monotonic:
AVAILABLE → RESERVED → CONFIRMED
- Re-processing an event that would “go backward” is ignored.
Interview signal: explicitly call out which API is idempotent and on what key.
2. Consistency: Preventing Double Booking
The hardest constraint
Booking systems must ensure exclusive ownership of inventory:
- One seat
- One time slot
- One room
Even under:
- High concurrency
- Multi-region traffic
- Partial failures
Common consistency strategies
Strong consistency (correctness-first)
- Row-level locking or compare-and-swap in a primary database.
- Single-writer per inventory shard.
- Pros: no overselling.
- Cons: lower throughput, regional latency.
Used when:
- Inventory is scarce (concert seats).
- Overselling is unacceptable.
Optimistic consistency (performance-first)
- Read availability → attempt write → fail if version changed.
- Conflicts handled via retries or user-visible failures.
- Pros: higher throughput.
- Cons: more failed attempts.
Used when:
- Inventory is plentiful.
- User retry is acceptable.
Partitioned ownership
- Inventory is partitioned so each item has a single logical owner.
- Eliminates cross-node coordination for most writes.
- Enables horizontal scale while preserving correctness.
Strong candidates explicitly justify where they draw the consistency boundary.
3. Availability: Staying Up Under Load and Failure
The tension
Booking systems live under constant tension:
- Consistency wants coordination
- Availability wants independence
Design goal:
Keep the system responsive without violating booking correctness.
Availability techniques
Fail-fast over incorrect
- If inventory ownership cannot be verified, reject the request.
- Never “guess” availability.
Graceful degradation
- Allow browsing even if booking is degraded.
- Return “temporarily unavailable” instead of blocking indefinitely.
Isolation of blast radius
- Inventory, payment, and notification failures are isolated.
- Booking state remains correct even if downstream systems fail.
4. Booking as a State Machine (Not a Single API)
A common mistake is treating booking as one atomic call.
Correct mental model:
Booking is a stateful workflow with strict transition rules.
Example states:
AVAILABLERESERVEDCONFIRMEDCANCELLED
Rules:
- Transitions are one-way or explicitly reversible.
- Replaying the same transition is safe.
- Invalid transitions are rejected.
This structure:
- Makes retries safe
- Simplifies reasoning under concurrency
- Prevents partial success bugs

