Building Ticketmaster
Implement the virtual waiting room with token-based admission, atomic seat holds with TTL, and the confirm-or-release flow.
The virtual waiting room
Users join a queue served by a lightweight, independently-scaled service; admission is rate- controlled so the booking core sees only a trickle:
def enter_queue(user, event_id):
pos = queue.push(event_id, user) # FIFO (or lottery) — Redis list/sorted set
return {"position": pos, "token": None}
def admission_loop(event_id): # admit at a sustainable rate
while sale_open(event_id):
capacity = booking_capacity(event_id) # how many the core can take now
for user in queue.pop_n(event_id, capacity):
token = issue_entry_token(user, event_id, ttl="10m") # signed admission token
notify(user, {"admitted": True, "token": token})
wait(throttle_interval)
The queue (position lookups, admission) runs on a cacheable store; the seat service never sees the herd — only token-bearing admitted users.
Gating the seat flow with the token
Every seat action requires a valid admission token, so non-admitted traffic can’t touch the core:
def select_seats(token, seat_ids):
user = verify_token(token) # reject if not admitted / expired
return hold_seats(user, seat_ids)
Atomic seat holds (no double-sell)
Selecting a seat atomically flips it available → held with a TTL — only one user can win
each seat:
def hold_seats(user, seat_ids):
held = []
try:
for seat in seat_ids:
ok = db.execute( # atomic conditional transition
"UPDATE seats SET status='held', held_by=:u, hold_expires=:exp "
"WHERE seat_id=:s AND status='available'",
u=user, s=seat, exp=now()+600)
if not ok: raise SeatTaken(seat) # someone else holds it
held.append(seat)
return held
except SeatTaken:
release(held) # all-or-nothing for the selection
raise
The WHERE status='available' makes the check-and-hold one atomic step — concurrent buyers
of the same seat can’t both succeed. A unique/exclusion guarantee per seat is the safety
net.
Hold expiry (don’t strand seats)
A background job (job scheduler) releases expired holds so abandoned carts free up seats:
def release_expired_holds():
for seat in seats.where(status="held", hold_expires_lt=now()):
db.execute("UPDATE seats SET status='available', held_by=NULL "
"WHERE seat_id=:s AND status='held'", s=seat.id)
Confirm or release
def checkout(token, seat_ids, payment):
user = verify_token(token)
charge(payment, price(seat_ids), idempotency_key=token+str(seat_ids)) # idempotent
with txn():
for seat in seat_ids:
ok = db.execute("UPDATE seats SET status='booked' "
"WHERE seat_id=:s AND status='held' AND held_by=:u",
s=seat, u=user)
if not ok: raise HoldLost(seat) # hold expired before pay → refund
issue_tickets(user, seat_ids)
If the hold lapsed before payment, the confirm fails and the charge is refunded — never sell a seat whose hold expired.
Fairness and anti-bot
- FIFO/lottery queue order; per-user ticket limits enforced at hold time.
- Anti-bot — CAPTCHA + rate limits + device/identity checks before queue entry; signed tokens prevent skipping the line.
Scale and failure handling
- Spike → absorbed by the queue; admission throttled to backend capacity (the core never overloads).
- Concurrent seat grabs → atomic conditional update; exactly one winner.
- Abandoned holds → TTL + sweeper free them.
- Payment fails / hold expired → confirm fails, refund, seat returns to available.
- Queue service failure → it’s decoupled and replicated; the seat core stays protected.
- Hot event → seat data sharded by event/section; the section being fought over is the contention point — atomic transitions serialize it correctly.
The takeaway
Concrete signals: a virtual waiting room with token-gated, rate-controlled admission (the herd never reaches the core), atomic seat holds with TTL (no double-sell under extreme concurrency), confirm-or-release with idempotent payment, and fairness + anti-bot. Admission control + atomic holds is the blueprint for any extreme-contention limited-inventory sale.