Bird
Raised Fist0
LLDsystem_design~15 mins

Reservation and hold system in LLD - Deep Dive

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Overview - Reservation and hold system
What is it?
A reservation and hold system is a software design that allows users to temporarily reserve or hold resources, like seats or items, before finalizing a purchase or booking. It manages availability so that no two users can claim the same resource at the same time. This system ensures fairness and prevents conflicts in resource allocation.
Why it matters
Without a reservation and hold system, multiple users could try to book the same resource simultaneously, causing confusion, double bookings, and poor user experience. It solves the problem of managing limited resources in real time, which is critical for businesses like airlines, hotels, or ticket sales. This system helps maintain trust and smooth operations.
Where it fits
Before learning this, you should understand basic data structures and concurrency concepts. After this, you can explore distributed locking, eventual consistency, and advanced inventory management systems.
Mental Model
Core Idea
A reservation and hold system temporarily locks resources to prevent conflicts while allowing users time to confirm their booking.
Think of it like...
It's like putting a 'reserved' sign on a restaurant table while you decide if you want to eat there, so no one else takes it during that time.
┌───────────────┐
│ User requests │
└──────┬────────┘
       │
       ▼
┌───────────────┐      ┌───────────────┐
│ Check resource│─────▶│ Is resource   │
│ availability  │      │ available?    │
└──────┬────────┘      └──────┬────────┘
       │ Yes                  │ No
       ▼                      ▼
┌───────────────┐      ┌───────────────┐
│ Place hold    │      │ Reject request│
│ (temporary)   │      │ or queue      │
└──────┬────────┘      └───────────────┘
       │
       ▼
┌───────────────┐
│ User confirms │
│ or cancels    │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Finalize or   │
│ release hold  │
└───────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding resource availability
🤔
Concept: Learn what it means for a resource to be available or unavailable in a system.
Resources like seats or items have a status: available means no one has claimed it, unavailable means someone else has it reserved or sold. The system must track this status accurately to avoid conflicts.
Result
You can identify if a resource can be reserved or not at any moment.
Knowing resource availability is the base for any reservation system because it prevents double booking.
2
FoundationBasic reservation process flow
🤔
Concept: Learn the simple steps of reserving a resource: check, hold, confirm or release.
When a user wants a resource, the system checks if it's free. If yes, it places a temporary hold. The user then confirms to finalize or cancels to release the hold. This flow ensures fairness and clarity.
Result
A clear process that prevents two users from booking the same resource simultaneously.
Understanding this flow helps grasp how reservation systems avoid conflicts.
3
IntermediateImplementing temporary holds with timeouts
🤔Before reading on: do you think holds should last forever or have a time limit? Commit to your answer.
Concept: Introduce the idea of time-limited holds to prevent resources being locked indefinitely.
Holds are temporary locks on resources that expire after a set time if the user doesn't confirm. This prevents resources from being stuck and unavailable to others forever.
Result
Resources become available again automatically if users don't act in time.
Knowing that holds must expire avoids resource starvation and improves system availability.
4
IntermediateHandling concurrent reservation requests
🤔Before reading on: do you think two users can hold the same resource at the exact same time? Commit to yes or no.
Concept: Learn how to manage multiple users trying to reserve the same resource simultaneously.
The system uses locking or atomic operations to ensure only one hold succeeds when multiple requests arrive at once. Others get rejected or queued.
Result
No two users can hold the same resource at the same time, preventing conflicts.
Understanding concurrency control is key to building reliable reservation systems.
5
IntermediateDesigning hold expiration and cleanup
🤔
Concept: Learn how to automatically release expired holds and keep the system clean.
The system tracks hold start times and uses background jobs or timers to release holds after timeout. This frees resources for others.
Result
Expired holds do not block resources, keeping availability accurate.
Knowing how to clean expired holds prevents resource locking and system clogging.
6
AdvancedScaling reservation systems with distributed locks
🤔Before reading on: do you think a single server can handle all reservations in a large system? Commit to yes or no.
Concept: Explore how to manage holds across multiple servers using distributed locking mechanisms.
In large systems, multiple servers handle requests. Distributed locks ensure only one server can hold a resource at a time, using tools like Redis or Zookeeper.
Result
Reservation consistency is maintained across servers, enabling scalability.
Understanding distributed locks is essential for building scalable, reliable reservation systems.
7
ExpertDealing with race conditions and eventual consistency
🤔Before reading on: do you think all reservation systems guarantee immediate consistency? Commit to yes or no.
Concept: Learn about challenges like race conditions and how some systems accept eventual consistency for performance.
Race conditions happen when two requests slip through checks simultaneously. Some systems use eventual consistency, allowing temporary conflicts resolved later, balancing speed and accuracy.
Result
Systems can handle high load with tradeoffs between consistency and performance.
Knowing these tradeoffs helps design systems that meet real-world demands without breaking.
Under the Hood
The system maintains a data store with resource states. When a hold request arrives, it uses atomic operations or locks to check and update the resource state to 'held'. A timer or background process tracks hold expiration, releasing resources if not confirmed. In distributed setups, consensus or distributed locking protocols coordinate state changes across nodes to prevent conflicts.
Why designed this way?
This design balances user experience and system integrity. Temporary holds give users time to decide without blocking resources indefinitely. Atomic operations and locks prevent race conditions. Distributed coordination allows scaling beyond single servers. Alternatives like no holds or first-come-first-served cause conflicts or poor availability.
┌───────────────┐
│ Client sends  │
│ hold request  │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Atomic check  │
│ and lock      │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Update state  │
│ to 'held'     │
└──────┬────────┘
       │
       ▼
┌───────────────┐      ┌───────────────┐
│ Start hold    │      │ Background    │
│ expiration    │◀─────│ process checks│
│ timer        │      │ expired holds │
└───────────────┘      └───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do holds guarantee a resource is yours forever? Commit yes or no.
Common Belief:Once I hold a resource, it is mine until I confirm or cancel.
Tap to reveal reality
Reality:Holds are temporary and expire after a timeout if not confirmed.
Why it matters:Assuming holds last forever can cause users to wait unnecessarily or lose resources unexpectedly.
Quick: Can two users hold the same resource at the exact same time? Commit yes or no.
Common Belief:Yes, because requests arrive simultaneously and the system processes them in parallel.
Tap to reveal reality
Reality:No, the system uses locking or atomic operations to ensure only one hold succeeds.
Why it matters:Believing simultaneous holds are possible leads to poor design and conflicts.
Quick: Does a reservation system always guarantee immediate consistency? Commit yes or no.
Common Belief:Yes, all reservation systems instantly reflect the latest state everywhere.
Tap to reveal reality
Reality:Some systems accept eventual consistency to improve performance under heavy load.
Why it matters:Expecting immediate consistency can cause unrealistic expectations and design complexity.
Quick: Is it okay to never release expired holds manually? Commit yes or no.
Common Belief:Yes, expired holds will clear themselves without intervention.
Tap to reveal reality
Reality:No, the system must actively detect and release expired holds to free resources.
Why it matters:Ignoring cleanup leads to resource starvation and system unavailability.
Expert Zone
1
Holds should be designed with user experience in mind; too short causes frustration, too long blocks resources.
2
Distributed locking introduces latency and complexity; sometimes optimistic concurrency with retries is preferred.
3
Race conditions can still occur in distributed systems; compensating transactions or conflict resolution strategies are necessary.
When NOT to use
Avoid reservation and hold systems for resources that are abundant or non-exclusive, where first-come-first-served or eventual allocation suffices. For extremely high-demand systems, consider queue-based or auction models instead.
Production Patterns
Real-world systems use a combination of in-memory caches for fast checks, persistent databases for durability, and distributed locks for coordination. They implement hold expiration with background workers and provide user notifications before hold expiry.
Connections
Distributed locking
Builds-on
Understanding distributed locking helps manage resource state consistently across multiple servers in reservation systems.
Concurrency control
Same pattern
Reservation systems apply concurrency control principles to prevent conflicting updates and ensure data integrity.
Traffic light control systems
Analogy in control and coordination
Both systems coordinate access to shared resources (roads or seats) to prevent conflicts and ensure smooth flow.
Common Pitfalls
#1Not setting a hold expiration time, causing resources to be locked indefinitely.
Wrong approach:holdResource(resourceId, userId) { // No expiration set resource.status = 'held'; resource.heldBy = userId; }
Correct approach:holdResource(resourceId, userId) { resource.status = 'held'; resource.heldBy = userId; resource.holdExpiresAt = currentTime + HOLD_TIMEOUT; }
Root cause:Misunderstanding that holds must be temporary to avoid resource starvation.
#2Allowing multiple holds on the same resource due to lack of atomic checks.
Wrong approach:if (resource.status == 'available') { resource.status = 'held'; resource.heldBy = userId; }
Correct approach:atomicCheckAndHold(resourceId, userId) { // Atomic operation ensures single success if (resource.status == 'available') { resource.status = 'held'; resource.heldBy = userId; return true; } return false; }
Root cause:Ignoring concurrency and atomicity in resource state updates.
#3Not cleaning up expired holds, leading to blocked resources.
Wrong approach:// No cleanup process function checkAvailability(resourceId) { return resource.status == 'available'; }
Correct approach:// Background job releases expired holds function cleanupExpiredHolds() { for each resource { if (resource.status == 'held' && resource.holdExpiresAt < currentTime) { resource.status = 'available'; resource.heldBy = null; } } }
Root cause:Assuming holds expire automatically without active cleanup.
Key Takeaways
Reservation and hold systems prevent conflicts by temporarily locking resources for users.
Holds must have expiration times to avoid blocking resources indefinitely.
Concurrency control and atomic operations are essential to prevent simultaneous holds on the same resource.
Distributed locking and cleanup processes enable scalable and reliable reservation systems.
Understanding tradeoffs between consistency and performance helps design systems that work well under real-world conditions.

Practice

(1/5)
1. What is the primary purpose of a hold in a reservation and hold system?
easy
A. To delete all reservations from the system
B. To permanently reserve a resource without expiration
C. To cancel a confirmed reservation immediately
D. To temporarily block a resource before final booking

Solution

  1. Step 1: Understand the role of a hold

    A hold temporarily blocks a resource to prevent others from booking it while the user decides.
  2. Step 2: Differentiate hold from reservation

    A reservation is permanent until canceled, while a hold expires if not confirmed.
  3. Final Answer:

    To temporarily block a resource before final booking -> Option D
  4. Quick Check:

    Hold = Temporary block [OK]
Hint: Holds are temporary blocks, not permanent reservations [OK]
Common Mistakes:
  • Confusing hold with permanent reservation
  • Thinking holds never expire
  • Assuming holds cancel reservations
2. Which data structure is best suited to track holds with expiration times efficiently?
easy
A. Simple array without ordering
B. Linked list without timestamps
C. Hash map with timestamps and a priority queue for expirations
D. Stack data structure

Solution

  1. Step 1: Identify requirements for hold tracking

    We need fast lookup by hold ID and efficient expiration handling.
  2. Step 2: Choose data structures

    A hash map allows quick hold lookup; a priority queue orders holds by expiration for timely removal.
  3. Final Answer:

    Hash map with timestamps and a priority queue for expirations -> Option C
  4. Quick Check:

    Hash map + priority queue = efficient hold tracking [OK]
Hint: Use hash map for lookup and priority queue for expirations [OK]
Common Mistakes:
  • Using unordered arrays causing slow expiration checks
  • Choosing stack which is LIFO, not suitable for expirations
  • Ignoring timestamps in data structure
3. Consider this pseudo-code for confirming a hold:
if hold.exists(hold_id) and not hold.is_expired(hold_id):
    reservation.create(hold.resource)
    hold.remove(hold_id)
    return "Confirmed"
else:
    return "Failed"
What will be the output if the hold has expired?
medium
A. "Failed"
B. "Confirmed"
C. Error due to missing hold
D. "Confirmed" but resource is double booked

Solution

  1. Step 1: Check hold existence and expiration

    The code confirms only if hold exists and is not expired.
  2. Step 2: Analyze expired hold case

    If hold is expired, condition fails and returns "Failed" without creating reservation.
  3. Final Answer:

    "Failed" -> Option A
  4. Quick Check:

    Expired hold = "Failed" confirmation [OK]
Hint: Expired holds cause confirmation to fail [OK]
Common Mistakes:
  • Assuming expired holds confirm successfully
  • Expecting errors instead of failure message
  • Ignoring hold expiration check
4. A developer wrote this code to release expired holds:
for hold in holds:
    if hold.expiration_time < current_time:
        holds.remove(hold)
What is the main issue with this code?
medium
A. Holds should not be removed, only marked expired
B. Modifying a list while iterating causes skipped elements or errors
C. Expiration time comparison is incorrect
D. Loop should use while instead of for

Solution

  1. Step 1: Understand iteration and modification

    Removing items from a list while iterating over it causes skipping or runtime errors.
  2. Step 2: Identify correct approach

    Use a separate list to collect expired holds or iterate over a copy to safely remove.
  3. Final Answer:

    Modifying a list while iterating causes skipped elements or errors -> Option B
  4. Quick Check:

    Remove during iteration = skipped elements [OK]
Hint: Never remove items from list while looping over it [OK]
Common Mistakes:
  • Ignoring iteration modification side effects
  • Assuming expiration comparison is wrong
  • Thinking loop type causes the issue
5. You need to design a scalable reservation and hold system for a popular event with thousands of simultaneous users. Which approach best ensures no double booking and timely hold expiration?
hard
A. Use distributed locks on resources, store holds with TTL in a distributed cache, and confirm with atomic transactions
B. Store all holds in a single database table without expiration, confirm by updating status
C. Allow multiple holds per resource and resolve conflicts manually later
D. Use client-side timers to expire holds and update server asynchronously

Solution

  1. Step 1: Prevent double booking with distributed locks

    Distributed locks ensure only one user can hold a resource at a time across servers.
  2. Step 2: Use TTL in distributed cache for hold expiration

    TTL automatically expires holds after timeout, preventing indefinite blocking.
  3. Step 3: Confirm holds atomically

    Atomic transactions guarantee reservation creation without race conditions.
  4. Final Answer:

    Use distributed locks on resources, store holds with TTL in a distributed cache, and confirm with atomic transactions -> Option A
  5. Quick Check:

    Distributed locks + TTL + atomic confirm = scalable, safe system [OK]
Hint: Combine distributed locks, TTL cache, and atomic confirm for scale [OK]
Common Mistakes:
  • Ignoring concurrency causing double booking
  • Relying on client-side expiration only
  • Not using atomic operations for confirmation