boot — loader
SHOHRABv2.0
$_
[ OK ]Initializing kernel...
Loading system...0%
Architecture6 minNov 2024

A Pattern for Handling Concurrent Seat Reservations

Distributed locking with Redis solved our double-booking problem at Offizonee. Here's how we used BullMQ queues and atomic transactions to guarantee no two users book the same seat.

At Offizonee, our event management platform needed to handle thousands of concurrent seat reservation requests without ever double-booking a seat. This is a classic distributed systems problem.

The Challenge

When 500 users try to book the last 50 seats simultaneously, naive database checks fail. By the time user A's INSERT runs, user B has already read the same "available" count. Both get confirmed — and you've oversold by 2x.

Our Solution: Three-Layer Defense

Layer 1: Redis Atomic Operations

We use Redis INCR/DECR operations on a seat counter key. These are atomic — no two requests can read the same value. Each reservation attempt decrements the counter; if it goes below zero, we reject the request.

Layer 2: BullMQ Job Queue

Instead of processing reservations inline, we push them to a BullMQ queue with a concurrency limit of 1 per event. This serializes writes to the database while keeping the API responsive. The queue consumer validates the reservation against the database and confirms or rejects it.

Layer 3: Database Constraints

A compound unique index on (event_id, seat_number) ensures that even if layers 1 and 2 fail, the database won't allow a duplicate.

Results

  • Zero double-booking incidents since launch
  • API response time under 50ms for reservation attempts
  • Handles 10K concurrent users during peak ticket sales
  • The pattern is reusable for any resource with contention: coupon codes, limited-edition items, or appointment slots.