SuryanandHome

Ticket Booking (Shows / Flights)

Problem statement

Sell limited seats fairly under massive concurrency (concert on-sale), prevent overselling, handle seat holds, payment timeout, and waitlists.

How it works

  • Hold: temporarily reserve seat IDs with TTL (e.g. 10 minutes).
  • Confirm: on payment success, convert hold to sold immutable record.
  • Release: TTL expiry or payment failure frees seats.

Analogy: Theater hold line: the agent puts a sticky note on 4 seats for 10 minutes while you run to the ATM; if you’re late, notes are removed.

High-level design

Rendering diagram…

Components explained — this design

ComponentWhat it isWhy we use it here
API Gateway + WAF + queue tokenEdge protection + optional waiting room token.Prevents instant sell-out bots from melting inventory service.
Virtual waiting roomAdmission control (CF Workers / vendor).Absorbs flash crowd; issues signed tokens to enter purchase flow fairly.
Booking serviceHolds seats, coordinates payment, commits order.Encapsulates saga steps and idempotency for checkout retries.
Redis hold locksShort TTL locks on seat/slot keys.Fast optimistic reservation; expires automatically if user abandons cart.
PostgreSQLDurable inventory and booking rows.Unique constraints are final anti-double-sell guardrails.
Stripe auth holdPre-authorizes funds without final capture.Reduces no-show revenue loss while avoiding capturing before seat confirmed.
POS webhookExternal truth for table availability.Bridges online inventory with in-restaurant reality.

Shared definitions: 00-glossary-common-services.md

Low-level design

Concurrency control

  • Pessimistic: SELECT ... FOR UPDATE on seat rows — serializes; bad at huge fan-in.
  • Optimistic: version column — many 409 conflicts on hot events.
  • Preferred for hot rows: Redis Lua script atomic HSETNX seat:F12 + expire; async reconcile to PostgreSQL with outbox pattern.

Waiting room

  • CloudFront + Lambda@Edge or Cloudflare Waiting Room to absorb burst; issue signed “shop token” admitting users gradually.

Idempotency

  • Idempotency-Key on checkout; unique (event_id, seat_id) constraint as final guard.

Search vs lock

  • OpenSearch for “find shows near me”; inventory remains source of truth in SQL.

E2E: purchase two adjacent seats

Rendering diagram…

Tricky parts

ProblemSolution
Double sellDB unique constraint + Redis as admission control only
BotsProof-of-work, CAPTCHA, device attestation
FairnessLottery after waiting room vs pure FCFS

Caveats

  • Airline GDS integration (Amadeus) is slow — design async holds + callback webhooks.
  • Refunds/chargebacks need compensating transactions (Saga).

Azure

  • Azure Queue for admission; SQL Server with rowversion; Front Door + WAF.