System Design Interview - The Double Booking Problem

Published on 18 Dec 2025
system design interview

One of the most common problems discussed in system design interviews is the double booking problem. You’ll encounter it in systems like hotel reservations, airline seat bookings, event ticketing, ride-hailing, or appointment scheduling.

At its core, the problem is simple:

How do you ensure that a resource (seat, room, slot) is not booked by more than one user at the same time?

In practice, this becomes challenging due to concurrent requests, distributed systems, network delays, and failures. Two users may attempt to book the same resource at the same moment, and without proper safeguards, the system could confirm both bookings.

In this post, we’ll explore common approaches to solving the double booking problem, focusing on the trade-offs interviewers expect you to understand.


Ways to Approach the Double Booking Problem

1. Database Row Locking with Status Flag

This is one of the most straightforward approaches.

How it works:

  • Each bookable resource (seat, room, slot) has a status column (e.g., AVAILABLE, BOOKED).

  • When a booking request arrives, the system:

    1. Starts a database transaction.

    2. Locks the row using SELECT ... FOR UPDATE.

    3. Checks if the status is AVAILABLE.

    4. Updates it to BOOKED.

    5. Commits the transaction.

Pros:

  • Simple and easy to reason about.

  • Strong consistency guarantees.

  • No external dependencies.

Cons:

  • Database locks reduce scalability.

  • Long-running transactions can block other users.

  • Not ideal for very high traffic systems.

Best for: Small to medium-scale systems with a single database.


2. Lock with Expiry Using Timeout Handling

To avoid holding locks indefinitely, systems often introduce temporary locks with expiration.

How it works:

  • When a user starts a booking, the system:

    • Places a lock on the resource with a TTL (e.g., 5 minutes).

    • Marks the resource as HELD instead of BOOKED.

  • If the user completes the booking within the timeout, the lock is confirmed.

  • If the user abandons the process, the lock expires automatically.

Pros:

  • Prevents deadlocks caused by crashes or abandoned sessions.

  • Improves user experience during multi-step booking flows.

Cons:

  • Requires cleanup logic for expired locks.

  • Edge cases when locks expire just before confirmation.

Best for: Booking flows involving multiple steps (seat selection → payment → confirmation).


3. Atomic Database Updates

This approach relies on the database’s ability to perform atomic operations.

How it works:

  • Instead of locking rows explicitly, the system uses a conditional update:

    UPDATE seats SET status = 'BOOKED' WHERE seat_id = ? AND status = 'AVAILABLE';
  • The booking is successful only if the affected row count is 1.

Pros:

  • No explicit locks.

  • High performance and simple logic.

  • Works well under moderate concurrency.

Cons:

  • Limited flexibility for complex workflows.

  • Still depends heavily on the database.

Best for: Simple booking logic where immediate confirmation is acceptable.


4. Distributed Locking with Redis

In distributed systems, database locks alone may not be enough.

How it works:

  • A distributed lock is created using Redis (e.g., SETNX with expiration).

  • Only the process that acquires the lock can proceed with booking.

  • Once completed, the lock is released.

Pros:

  • Works across multiple application instances.

  • Fast and scalable.

  • Reduces load on the primary database.

Cons:

  • Adds operational complexity.

  • Requires careful handling of lock expiration and failure cases.

  • Incorrect implementation can lead to race conditions.

Best for: Large-scale, distributed systems with high concurrency.


5. Queue-Based Processing

Another approach is to serialize booking requests using a queue.

How it works:

  • All booking requests for a resource are sent to a message queue.

  • A single consumer (or partitioned consumers) processes requests sequentially.

  • Only one booking can be processed at a time.

Pros:

  • Eliminates race conditions entirely.

  • Smooths traffic spikes.

  • Easy to reason about ordering.

Cons:

  • Increased latency.

  • More infrastructure to maintain.

  • Not ideal for real-time user interactions.

Best for: High-demand systems where consistency is more important than low latency.


6. Booking Only Successful After Payment

A practical real-world approach is to treat payment as the final source of truth.

How it works:

  • Booking is considered tentative until payment succeeds.

  • The resource is temporarily held during checkout.

  • Only after payment confirmation is the booking finalized.

  • Failed or timed-out payments automatically release the resource.

Pros:

  • Reduces ghost bookings.

  • Aligns business logic with revenue.

  • Works well with timeout-based locks.

Cons:

  • Requires careful handling of payment failures.

  • Slightly more complex state management.

Best for: E-commerce, travel, and ticketing platforms.


Summary

The double booking problem is fundamentally about handling concurrency safely. There is no single “correct” solution—only trade-offs.

  • Database locking is simple but doesn’t scale well.

  • Timeout-based locks improve user experience in multi-step flows.

  • Atomic updates offer speed and simplicity.

  • Redis distributed locks enable horizontal scalability.

  • Queue-based processing ensures strict consistency at the cost of latency.

  • Payment-first confirmation aligns system design with business realities.

In system design interviews, interviewers care less about the specific technique you choose and more about why you choose it, how it scales, and how it handles failures.

Understanding these approaches—and when to use each—will help you confidently tackle any double booking discussion in your next interview.