ServicesWaiting Room

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 as active from that point), and eventually leaves, expires, or is rejected. Once admitted, position responses drop the position field.
  • Queue strategies - fifo (default), priority (higher priority value is admitted first), or random.
  • Admission is manual (admit by 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 refresh periodically; a cleanup worker evicts expired sessions so abandoned members do not hold capacity.
  • Groups - members who join with the same group_id can 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-day

get 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.
  • delete refuses a room that still has members: 409 CONFLICT - Room is not empty. Empty it first.
  • --auto-admit is a bare flag on create but takes a value on update (--auto-admit true|false).
  • The CLI list only paginates; the HTTP GET /api/v1/waiting-rooms endpoint also accepts filter (on status, queue_strategy, created_by, capacity) and sort_by/sort_order from 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-day

Over 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 3600

The 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" } ]
}
  • members lists every status when -s is omitted; pass -s (waiting, admitted, active, expired, rejected) to filter.
  • Admitted members are listed under -s active with an admitted_at timestamp; 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-42

group-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-day

Returns 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

On this page