High-concurrency concert ticket sales with a server-authoritative waiting room, anti-scalping controls, and reproducible load tests for every major failure mode from the BookMyShow sale incidents.
| Issue | Fix | Test scenario |
|---|---|---|
| Site crash at sale open | Virtual waiting room + admission drip + rate limits | launch_spike |
| HTML/API backdoor | No client queue secrets; phase-gated join; admission JWT for checkout | backdoor_race |
| Late users got ahead | Atomic FIFO position at join; idempotent re-join | queue_fairness, late_surge, second_sale_regression |
| Black market / bots | Non-transferable tickets, caps, rate limits | bot_checkout, scalper_network |
| Refresh loses queue spot | Position stored server-side per account | refresh_storm, reconnect_churn |
Easiest — one command:
git clone <repo-url> traffic && cd traffic
make desktop
open http://localhost:8080Or: ./scripts/run-traffic.sh — see Run with Docker for zip download, pre-built images, and sharing with testers.
Developers (same stack, manual compose):
make up # postgres, redis, api, worker, loadtest-runner
open http://localhost:8080 # Load Control Center UIThe UI lets you pick a scenario, set peak VUs, ramp timings, and sale capacity (admit rate, waiting room cap, seats), then Start load test. k6 runs in the loadtest-runner sidecar; results show PASS/FAIL against SLO thresholds. The black sidebar shows live queue depth, admits, and a queue sparkline during the run.
make seed # optional CLI demo sale
make assert-queue SALE_ID=$SALE_ID- Open http://localhost:8080
- Use a preset (T+0 launch, Refresh storm, Fairness audit, …) or configure manually
- Reset sale for a clean queue (optional; auto-created on first run)
- Start load test — poll status until PASS/FAIL
- Watch Live performance while k6 runs
| Control | Env (CLI) | Default |
|---|---|---|
| Peak VUs | K6_VUS_MAX |
500 |
| Ramp up / steady / down | K6_RAMP_UP, K6_STEADY, K6_RAMP_DOWN |
10s / 30s / 10s |
| Admit rate | K6_ADMIT_PER_MIN |
6000 |
| Waiting room cap | K6_WAITING_ROOM_CAP |
100000 |
| Total seats | K6_TOTAL_SEATS |
500 |
make up
make sim SCENARIO=launch_spike
make sim SCENARIO=launch_spike K6_VUS_MAX=200 K6_STEADY=20sRequires the loadtest compose profile (included in make up).
After a test, verify queue invariants:
go run ./cmd/assert-queue -sale $SALE_ID
curl -s -H "X-Admin-Key: dev-admin-key" http://localhost:8080/v1/admin/sales/$SALE_ID/queue-entries | jq .POST /v1/auth/register— create accountPOST /v1/sales/{id}/waiting-room/join— join queue (idempotent)GET /v1/sales/{id}/waiting-room/status— poll; refreshing does not change position- Seat map / holds / checkout require
Authorization: Admission <jwt>from status when admitted POST /v1/tickets/transfer— always 403 (non-transferable)
Demo lab API (local dev only):
POST /v1/demo/reset— fresh demo sale with optional capacity paramsPOST /v1/demo/loadtest— queue a k6 run (scenario,vus_max, ramps, sale settings)GET /v1/demo/loadtest/{runId}— run status + PASS/FAIL + metricsGET /v1/demo/loadtests— recent runs + scenario listGET /v1/demo/dashboard— live queue depth, tickets, error rate
Admin (X-Admin-Key: dev-admin-key): POST /v1/admin/events, POST /v1/admin/sales, stats, queue audit
- Metrics: http://localhost:8080/metrics
- Health:
/health/live,/health/ready - k6 summaries: Docker volume
loadtest_results(also surfaced via API)
- Git clone on each PC (easiest): Share with testers —
git clone→make desktop - Pre-built images + zip: Run with Docker
- Cloud (optional): Deploy guide or Oracle Always Free
- How it works — plain-language overview of the system and anti-crash logic
- Deploy for shared testing
- BookMyShow postmortem mapping
- Capacity assumptions
- Load test results template
- ADRs
Go, PostgreSQL, Redis, chi, Prometheus, k6, Docker Compose.