Concurrency is the number of calls that can be in progress at the same time in a workspace. Inbound, outbound, web and batch calls all share one limit. You manage it on Settings, Limits.
Concurrent calls limit#
| Property | Value |
|---|---|
| Default | 20 per workspace |
| Range | 1 to 1,000 |
| Who can change it | Admins (Adjust Concurrency, or PATCH /workspace with concurrency_limit) |
| Included in the price | 20 slots (TRIED_INCLUDED_CONCURRENCY) |
| Extra slots | $12 per slot per month |
The card shows Concurrent Calls Limit and a bar of Calls in progress right now. GET /get-concurrency returns the same numbers:
{
"current_concurrency": 4,
"concurrency_limit": 20,
"base_concurrency": 20,
"purchased_concurrency": 0,
"reserved_inbound_concurrency": 2,
"concurrency_burst_enabled": false,
"concurrency_burst_limit": 20
}Purchased slots#
Raising the limit above the included 20 buys slots at $12 per slot per month. The charge is taken from credit the first time the hourly billing job sees the higher limit in a month, and again each month. If you raise the limit mid-month, only the new slots are charged. The Concurrency card on Billing shows Limit, Included, Purchased and recent charges.
What happens when every slot is busy#
| Call type | Behaviour |
|---|---|
Outbound (create-phone-call) |
429. The call is not created |
| Web call | 429 |
| Batch call | Each batch tick dials only as many tasks as there are free slots (minus the batch's reserved_concurrency); the rest wait for the next tick |
| Inbound | The caller is held and the API polls for a free slot for up to 40 seconds (INBOUND_QUEUE_TIMEOUT_MS). Then the agent answers, or the call is transferred to the number's fallback_number, or it ends with no_concurrency_fallback |
Reserved inbound slots#
Reserved inbound slots holds back part of the limit for inbound calls. Outbound, web and batch calls can't use these, so inbound callers always find a free line. Set a whole number between 0 and your limit.
Burst concurrency#
With Burst concurrency on, the workspace admits calls above its limit when traffic spikes, up to the lower of 3 times the limit and the limit plus 300. Calls admitted above the limit are flagged concurrency_burst: true and cost an extra $0.15 per minute (concurrency_burst line on the call cost).
Both settings are saved with PATCH /update-concurrency-settings:
{ "reserved_inbound_concurrency": 2, "burst_enabled": true }Concurrency calculator#
Click Concurrency calculator and enter Calls per day, Average call length (minutes) and Business hours per day. The recommendation is the average load with 1.5 times headroom for peaks:
recommended = ceil(calls_per_day / (hours x 60) x minutes x 1.5)For 1,000 calls a day of 3 minutes over 8 hours, that is ceil(1000 / 480 x 3 x 1.5) = 10.
Calls per second (CPS)#
Outbound dials are paced per phone number with a token bucket.
| Number type | Default CPS |
|---|---|
| Telnyx numbers | 4 (DEFAULT_CPS_TELNYX) |
| Imported numbers on your own trunk | 10 (DEFAULT_CPS_CUSTOM) |
Set cps_limit on a number to override it. A dial waits up to 5 seconds for a token (CPS_MAX_WAIT_MS), then returns 429. Batch calls pace on the same buckets.
LLM token limit#
The workspace LLM token limit caps the context the voice runtime sends to the model on each turn. The default is 32,768 tokens and it can be set from 1,024 to 131,072 on Settings, Reliability (admin). When a conversation grows past it, the runtime drops the oldest turns and keeps the system prompt. A tool call and its result are dropped together. Replies stay capped at 300 completion tokens.
API rate limits#
Separate from call concurrency, API requests are rate limited per API key (600 per minute by default) and per IP (3,000 per minute). See API keys.