Waiting Room
Virtual waiting rooms for scarce capacity: rooms with FIFO, priority, or random admission, manual and automatic admission, TTL-based sessions with refresh, group fast-tracking, anti-gaming protections, and per-room analytics.
When to reach for it: product-drop launches, ticket on-sales, beta access gating, game login queues, flash sales, ordered admission to any capacity-limited resource.
When not to: background work that machines process belongs to Job Queue; pairing players by skill belongs to Matchmaking.
Concepts
- Rooms carry a capacity and a status (
active,paused,disabled). Room management, admission, member listing, analytics, and bans require a platform admin token; joining and polling do not. - Member lifecycle - a member joins as
waiting, then is admitted (shown asactivefrom that point), and eventually leaves, expires, or is rejected. Once admitted, position responses drop thepositionfield. - Queue strategies -
fifo(default),priority(higherpriorityvalue is admitted first), orrandom. - Admission is manual (
admitby count or by member IDs) or automatic: with auto-admit on, a background sweep promotes waiters whenever capacity is open. - Sessions - if the room sets a session TTL, admitted members must
refreshperiodically; a cleanup worker evicts expired sessions so abandoned members do not hold capacity. - Groups - members who join with the same
group_idcan be checked and admitted together as one atomic unit. - Anti-gaming and bans - rejoin cooldowns, join rate limits, and a ban registry have their own page: Bans and anti-gaming.
Create and manage rooms (admin)
snug waiting-room create -r launch-day -c 100 -s priority --session-ttl 600
snug waiting-room list
snug --output json waiting-room get -r launch-day
snug waiting-room update -r launch-day -c 200 -s paused
snug waiting-room delete -r launch-dayget returns the room configuration plus live statistics
(active_count, waiting_count, total_admitted,
average_wait_seconds, current_admission_rate). Verified behaviors:
- Creating an ID that already exists fails with
409 CONFLICT-Room already exists. deleterefuses a room that still has members:409 CONFLICT-Room is not empty. Empty it first.--auto-admitis a bare flag oncreatebut takes a value onupdate(--auto-admit true|false).- The CLI
listonly paginates; the HTTPGET /api/v1/waiting-roomsendpoint also acceptsfilter(onstatus,queue_strategy,created_by,capacity) andsort_by/sort_orderfrom the shared search grammar.
Join and wait
snug waiting-room join -r launch-day -p 75 # -p matters only in priority rooms
snug --output json waiting-room position -r launch-day
snug waiting-room refresh -r launch-day # extend the session TTL
snug waiting-room leave -r launch-dayOver HTTP, joining is a POST with an optional priority, group, and
metadata; captured live:
curl -X POST -H "Authorization: Bearer $SNUG_API_TOKEN" \
-H "Content-Type: application/json" -d '{"priority": 0}' \
http://localhost:4000/api/v1/waiting-rooms/launch-day/join{
"status": 201,
"msg": "Created",
"data": {
"room_id": "launch-day",
"member_id": "docs4-other",
"position": 2,
"estimated_wait_seconds": 0,
"status": "waiting",
"joined_at": "2026-08-28T14:15:27.135772Z",
"priority_group": "standard"
}
}position polls the caller's own place in line and adds ahead_count
and priority_effective. In a priority room the order is by priority,
not arrival - verified: a member joining with -p 100 landed at position
1 ahead of an earlier member with -p 10, while the same experiment in a
fifo room left arrival order untouched. estimated_wait_seconds is
derived from the room's admission rate (batch_size per
interval_seconds).
Joining a room twice fails with 409 CONFLICT - Already in queue, and
polling or leaving when not queued is 404 NOT_FOUND - Not in queue.
refresh returns the new expiry as a Unix timestamp:
{"success": true, "new_expiry": 1787927148}.
Admitting members (admin)
snug waiting-room members -r launch-day -s waiting
snug waiting-room admit -r launch-day -c 10 # next 10 by strategy order
snug waiting-room admit -r launch-day -m user-1,user-2 # specific members
snug waiting-room reject -r launch-day -m user-3 -R "abuse" -b 3600The admit response reports both outcomes; captured live admitting a member ID that was not queued:
{
"admitted": [],
"capacity_reached": false,
"failed": [ { "member_id": "docs4-ghost", "reason": "Not in waiting queue" } ]
}memberslists every status when-sis omitted; pass-s(waiting,admitted,active,expired,rejected) to filter.- Admitted members are listed under
-s activewith anadmitted_attimestamp; there is no separate "admitted but not active" listing. reject -b <seconds>combines removal with a temporary ban - see Bans and anti-gaming.
Auto-admission
With auto-admit on, a background sweep promotes waiters whenever the
room has free capacity - verified: a member joined as waiting and was
active roughly ten seconds later with no manual admit. The sweep runs
on a server-wide cadence (WAITING_ROOM_AUTO_ADMIT_INTERVAL_SECONDS,
default 10) admitting up to the room's batch_size per pass; the room's
interval_seconds only feeds the wait-time estimate, not the cadence.
Groups
snug waiting-room join -r launch-day -g vip-42
snug --output json waiting-room group-status -r launch-day -g vip-42
snug waiting-room admit-group -r launch-day -g vip-42group-status lists the group's members with positions and a
can_be_admitted verdict (does free capacity fit the whole group);
admit-group then admits every member atomically - verified with a
two-member group into a capacity-2 room (capacity_reached: true).
Analytics (admin)
snug --output json waiting-room analytics -r launch-dayReturns a summary (total admissions, rejections, abandonments, their
rates, and min/avg/max wait seconds) plus hourly buckets over the
queried window, retained for 7 days by default.
Limits and configuration
Room count cap (10,000 by default), auto-admit cadence and per-pass batch
cap, and the session, ban, and analytics cleanup intervals are tunable
via the WAITING_ROOM_* variables in the
Waiting Room CONFIG reference.
Reference
- Waiting Room API - every endpoint, callable
- Bans and anti-gaming - cooldowns, rate limits, the ban registry
- Related: Job Queue for machine work queues, Matchmaking for skill-based pairing