RustPBX Basics: Queues & ACD — Fairness, Priority, and the Overflow Ladder
Queues are where callers decide whether your company has its act together. The ACD (Automatic Call Distribution) engine has to balance three promises: fairness (first come, first served), priority (VIPs really do go first), and escape (nobody waits forever). Here’s how RustPBX delivers each.
Strategy: Picking the Agent

Five assignment algorithms cover the standard rotations:
| Algorithm | Behavior |
|---|---|
longest_idle | Longest-idle agent first (default) |
least_answered | Protects new agents |
round_robin | Even distribution |
skill_based | Weighted scoring: skill_match × 0.6 + idle_time × 0.3 + priority × 0.1 |
random | Special cases |
Skill weights are configurable per policy, and require_exact_skill toggles between “at least one skill” and “all skills” matching.

Priority Without Starvation
Every waiting call has a score: base_priority + vip_bonus + wait_time × weight. VIP bonuses are mapped by tier, and the wait-time weight means a caller’s score climbs every second — so a silver customer waiting 5 minutes outranks a gold customer who just called. Within the same priority, dispatch is FIFO, and in clusters the FIFO gate is strict across nodes.
Overflow: The Ladder
Overflow triggers (timeout / queue length / no agents) push calls down a chain: another skill group, voicemail, callback, back-to-IVR, or hangup. Three modes decide how the chain is walked:
replace— hand off to the next groupcumulative— ring original + overflow groups togethersequential— dwell in the current queue, then re-queue into the next group in order
sequential is the polite one: agents downstream only get interrupted for calls that genuinely ran out of time upstream. Every hand-off emits an overflow_joined event.
The Comfort Layer
- Queue hold music as a PBX-wide default (
queue_hold_music), overridable per queue. - Screen-pop headers (
Call-Info/User-to-User) re-applied on every re-ring — see the screen-pop post. - Queue-entry traces with the resolved agent, so each dispatch decision is auditable.
Watching It Live

GET /cc/realtime and the monitor page show per-queue waiting depth, longest wait, and agent states — reconciled against the shared queue tracker, not a single in-memory counter. Full configuration: Queues & ACD.
A Real-World Recipe: The VIP Line
Putting it together — a VIP number that must never wait long:
- A route rule matches the VIP DID and sets
base_priorityvia queue metadata - The queue uses
skill_basedwithrequire_exact_skill = true(only fully-trained agents) - Overflow after 30s → senior group,
sequentialmode, then voicemail - Screen-pop headers carry the customer id; CSAT survey with after-transfer opt-in
Four config blocks, no code — and every step above links to a full guide in the docs.