Skip to main content
The fleet Each node reports itself, and carries three limits that run out independently. All three are enforced: a call past one is refused before it is answered, so the calls already up keep their audio. A relayed call costs 0 units. Opus against G.711 costs 2, G.729 or iLBC against Opus costs 4, G.726 against G.711 costs 1, and a virtual agent adds 3 — so the transcode figure is what a node actually runs out of, and a node can be comfortable on channels and out of budget. The Overview shows each as in use / limit.
The audio-streaming module this project builds is free for ten concurrent streams, and a call past the module’s own limit is not refused by it — it is answered and silent. That is why the node refuses first, and why the default is 8: live assist draws on the same ten.
Limits are re-read every 30 seconds, so lowering one during an incident takes effect without a restart.

When the machine itself is loaded

A counted limit can only see calls. On a box shared with anything else — a database, a mail server, other sites — a neighbour taking a core is not a channel, and every gauge still reads fine while audio breaks on every call at once. So the node also watches the machine: Calls this platform chose to make — campaigns, API-placed AI calls — are shed first; a person who clicked to call is refused only when everything is. The Overview shows a badge while it is happening, with what the machine was doing. An API call refused this way answers 503 node_busy with Retry-After: 30: “try again shortly”, as distinct from 422, “this request is wrong”.

Keeping transcode low

Both legs agreeing on a codec lets the switch relay rather than transcode. That is the difference between near-zero CPU and the most expensive thing the system does — see extensions.

Which codecs a node speaks

Opus and G.711 always. G.729, iLBC and G.726 are separate modules, built with the switch (deploy/node/build-g729.sh, deploy/node/build-codecs.sh) and loaded only where they are installed. A node without one still takes the call: every codec profile and every sensible trunk list keeps G.711 behind its first choice, so the call connects in G.711 instead. verify.sh names any module that is installed and not loaded. On a trunk they are ticked, not typed — see a trunk’s codecs. Through the API the names are G729, iLBC and G726-32: the rate is part of the name, and a bare G726 is refused because the switch would drop it from the offer without saying so. When a trunk is pinned to a node, its editor says so if a ticked codec’s module is not loaded there.

Admission control

A node refuses new calls beyond its configured session limit rather than degrading everything already in progress. The switch’s own limit is per second as well as total, and it is shared with everything arriving inbound — which is why a wide outbound campaign competes with your tenants’ incoming calls. The same is true of a carrier: a trunk’s channel limit counts both directions, because that is what the carrier contracted. Where a dialling burst must not be able to fill it, set the trunk’s outbound channel limit as well — it caps the outgoing share and reserves the rest for calls arriving. See trunks.

The name desk phones use

A node’s Handset server name (e.g. sip.firet.one) is what every extension’s handset settings name as the server. It is display only — nothing is written to the switch — but a phone using TLS on 5061 needs it: the phone checks the certificate against the server it was given, and a certificate names a host, not an address. Leave it empty and extensions show the advertised address, which is fine for UDP and TCP on 5060.
The name must resolve to this node directly. A website domain behind Cloudflare (or any web proxy) resolves to the proxy, which carries HTTP only: a phone given it never reaches the switch, and nothing on the switch shows a thing. Use a name that is not proxied — getent ahosts <name> must print the node’s own address. The extension’s handset settings and verify.sh both check it and say so when it leads elsewhere.
The switch listens for SIP on IPv4 only. A name with an IPv6 (AAAA) record sends a phone that prefers IPv6 to an address nothing answers on. An organisation’s handsets are shown the node chosen on the organisation, or the only node there is. With several nodes and none chosen, the handset settings say so instead of guessing.