Calls Per Second (CPS)

Control how fast your outbound calls start, so a big campaign never overruns your phone carrier.
View as Markdown

Calls per second (CPS) is how many new outbound calls the platform is allowed to start each second.

It is easy to confuse with concurrency, so here is the difference in one line: concurrency is how many calls can run at the same time. CPS is how fast new ones can begin. Both limits apply together.

The question it answersThink of it as
CPSHow fast can new calls start?How wide the door is
ConcurrencyHow many calls can run together?How many seats are in the room

Example. You launch a campaign of 5,000 contacts with 2 CPS and 50 concurrency. The platform starts two calls every second. After 25 seconds all 50 seats are full. From then on, every time a call ends and frees a seat, a new call starts, but never more than two in any second.

Concurrency page showing the Calls per second section with Plivo and Twilio rates for rented numbers and one imported SIP trunk at 1 call per second
The Concurrency page. Reserved concurrency at the top, then the Calls per second section with your rented-number rates and your own SIP trunks.

CPS only applies to outbound calls, the ones the platform dials: API calls, campaigns, automatic retries, and test calls. Inbound calls are not paced. They arrive at whatever speed people call you.

Why CPS exists

Every phone carrier has a limit on how many calls it will accept per second on a trunk. If you send more than that, the carrier rejects the extra calls. Those calls never connect, and they show up as failures in your reports. If it keeps happening, the carrier may throttle or suspend the trunk.

Before CPS, the only protection was to slow down on your side: send calls to our API a few at a time so you never exceeded your carrier’s limit. That is fiddly, and it wastes the queue.

With CPS you do the opposite. Send us everything at once. Push 10,000 calls in one go, tell us the rate your carrier accepts, and we hold the calls in a queue and release them at exactly that rate. Nothing is dropped. Calls simply wait their turn.

CPS is included with your plan at no extra cost. You pay for concurrency, not for pacing.

Where the limit comes from

Your phone numbers come from one of two places, and the CPS limit is set differently for each. The Calls per second (CPS) section of the Concurrency page shows them as two groups, using the same names as below.

Rented numbers · Smallest telephony

Numbers you rent from Smallest, on our Plivo or Twilio accounts. We own the carrier relationship, so the rate is set for you, one per provider. You can see it but not change it in the dashboard.

Imported numbers · Your SIP trunks

Numbers you brought over SIP from your own carrier. You own the carrier relationship, so you set the rate to match what your carrier allows. Org admins can edit it.

Rented numbers (Smallest telephony)

One rate per provider. Each provider’s rate covers all your rented numbers on it. If you rent eight Plivo numbers, they share the Plivo rate. They do not get one each.

Each provider card shows one of two messages:

  • “Reserved for your organization. Contact support to change it.” A rate that is yours alone. In the screenshot above, Plivo is reserved at 5 calls/sec and Twilio at 1 calls/sec.
  • “Standard plan rate. Contact support to reserve dedicated CPS.” The shared rate that comes with your plan, when you have no reservation.

Either way, changing it is a plan setting, not a dashboard toggle. Contact support.

Imported numbers (Your SIP trunks)

Imported numbers dial through your own carrier and are grouped by SIP trunk. A trunk is identified by its address, for example 43.205.53.11:5091 in the screenshot. The row shows how many numbers are on it (1 number on this trunk) and its rate in calls/sec. Every number on a trunk shares that one rate.

This grouping matters. Carriers enforce CPS on the trunk, not on each number. If 30 of your numbers sit on one trunk that accepts 2 calls/sec, all 30 together must stay under 2 calls/sec. Pacing each number at 2 would hit the trunk with 60 attempts a second.

Set each trunk’s CPS to what your carrier actually allows. If you are not sure, ask your carrier before you raise it. This number is what protects you from rejected calls. Every new trunk starts at 1 call/sec, the safe default when the real limit is unknown.

Numbers imported against the same address join the same trunk and inherit its rate. Small differences in how you type the address do not create a new trunk: sip:trunk.example.com:5060;transport=udp and trunk.example.com:5060 are treated as the same trunk. A different port is treated as a different trunk, because it can genuinely be a different endpoint.

Setting a trunk’s CPS

1

Open the Concurrency page

In the sidebar under Configure, click Concurrency and scroll down to Calls per second (CPS). Rented numbers are shown first. Imported numbers are listed below, one row per SIP trunk, with the numbers on it.

2

Edit the trunk

Click Edit on the trunk row, enter the new rate in calls/sec, and save. You can set any whole number from 1 to 50.

3

Check the total

The row shows the new rate, and Total across trunks at the top right of the Imported numbers group updates.

Only org admins can change a trunk’s CPS. Members can view the page. This is the same rule as for concurrency reservations, because a wrong value can cause your carrier to reject calls for the whole organization.

Changes apply within about a second

A CPS change applies to calls already waiting in the queue, not only to new ones. If you lower a trunk from 20 to 2 in the middle of a campaign, the calls already queued slow to 2 per second within about a second. Raising the rate speeds them up just as quickly.

This is useful when something goes wrong. If your carrier starts rejecting calls, lower the rate and the queue respects it immediately.

The rate belongs to the trunk, so one edit changes every number on it. You never edit numbers one at a time.

What happens when you send calls faster than the rate

Nothing is dropped. Calls that arrive faster than the rate allows wait in the queue and start as the rate permits, in the order you sent them. A burst of 600 calls on a 4 calls/sec trunk finishes starting in about 150 seconds.

Two different limits can hold a call back. Here is how to tell them apart:

What you seeWhich limitWhat to do
Calls start slowly but steadily, in orderCPS. Calls are being paced.Raise the trunk’s CPS, if your carrier allows it
Calls start fast, then stall and resume in burstsConcurrency. All seats are taken.Raise concurrency, or reserve seats for the agent

Planning your total rate

Some carriers cap CPS across your whole account, not only per trunk. If yours does, watch Total across trunks and keep it within that limit. The page says the same thing under the trunk list: “If your provider limits CPS across your whole account, keep the total above within that limit.”

Adding a trunk raises the total. If your carrier’s account limit is 10 calls/sec and you already have two trunks at 5 each, importing a number on a third trunk at the default 1 call/sec puts you at 11.

Managing CPS through the API

Both endpoints use the standard Atoms API base URL and your API key. See API Keys. Full request and response schemas are in the API reference: Get CPS limits and Set a SIP trunk’s CPS.

View your CPS settings

cURL
$curl -X GET "https://api.smallest.ai/atoms/v1/product/cps-limits" \
> -H "Authorization: Bearer $SMALLEST_API_KEY"

Returns your rented-number rate per provider, your SIP trunks with the numbers on each, and the total across trunks:

1{
2 "status": true,
3 "data": {
4 "providers": {
5 "plivo": { "cpsLimit": 5, "isUnlimited": false },
6 "twilio": { "cpsLimit": 1, "isUnlimited": false }
7 },
8 "trunks": [
9 {
10 "terminationUrl": "43.205.53.11:5091",
11 "cpsLimit": 1,
12 "numbers": [
13 {
14 "trunkId": "6a1b2c3d4e5f60718293a4b5",
15 "phoneNumber": "+919240923804",
16 "name": "68c8f7c3a0a8ef01e4fb72fd-919240923804-vqrtq8foxf",
17 "isActive": true
18 }
19 ]
20 }
21 ],
22 "totalCps": 1
23 }
24}

For a provider, cpsLimit: null with isUnlimited: false means you have no reservation and are on your plan’s standard rate. isUnlimited: true means an unlimited reservation.

Each entry in numbers is one phone number on the trunk. trunkId is the id of the SIP trunk record that number belongs to, and name is the trunk record’s name, which is generated automatically when you import.

Set a trunk’s CPS

cURL
$curl -X PATCH "https://api.smallest.ai/atoms/v1/product/custom-trunk/cps-limit" \
> -H "Authorization: Bearer $SMALLEST_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "terminationUrl": "43.205.53.11:5091",
> "cpsLimit": 2
> }'
FieldRequiredNotes
terminationUrlYesThe trunk address to update. Normalized the same way as at import, so it does not need to match character for character.
cpsLimitYesWhole number from 1 to 50. Applies to every number on the trunk.

The response tells you how many trunk records were updated:

1{ "status": true, "data": { "trunksUpdated": 1 } }
StatusMeaningExample error
200Applied.
400cpsLimit is outside 1 to 50, not a whole number, or terminationUrl is missing.CPS limit cannot exceed 50
403You are not an org admin, or not a member of the organization.
404Your organization has no SIP trunk at that address.No SIP trunk on that address for your organization

Errors come back as { "status": false, "errors": ["..."] }.

There is no endpoint for rented-number rates. Those are plan settings. Contact support to change them.

Good habits

The most useful thing you can do is find out what your trunk actually accepts and set exactly that. Guessing high causes rejected calls. Guessing low only makes campaigns slower than they need to be.

If you currently send requests slowly to protect your trunk, you can stop. Set the trunk’s CPS and send everything at once. The queue does the pacing, and you get better throughput because the queue is always full.

A campaign submits its contacts quickly. Set the trunk’s CPS first, so the whole batch is paced correctly from the first call.

CPS controls how fast calls start. Concurrency controls how many run together. A high CPS with low concurrency starts calls fast and then makes them wait for a seat anyway. See Concurrency for reserving seats per agent.

Per-trunk limits protect each trunk, but they do not stop the sum from going over an account-level cap. Check Total across trunks whenever you add a trunk.

FAQ

CPS limits how fast new calls start. Concurrency limits how many calls run at the same time. A call needs both: the trunk must be within its CPS rate, and there must be a free concurrency seat.

No. They wait in the queue and start in order as the rate allows. CPS changes when a call starts, never whether it happens.

Within about a second, and it applies to calls already queued, not only new ones.

Because that is how carriers enforce it. The limit lives on the trunk, so every number on it draws from the same allowance. Pacing each number separately would multiply your real rate by the number of numbers.

One trunk, as long as the host and port match. The scheme prefix (sip:), capitalisation, and URI parameters such as ;transport=udp are ignored. Different ports are different trunks.

1 call/sec. It is the safe floor when the real limit is unknown. A number imported onto a trunk you already have inherits that trunk’s rate.

50 calls/sec per trunk. If your carrier supports more and you need it, contact support.

No. Every trunk is paced, with a minimum of 1 call/sec. An unpaced trunk is exactly what gets calls rejected by the carrier.

No, and it would not protect you. The carrier’s limit is on the trunk, so only a rate shared by every number on that trunk keeps you under it.

Org admins, the same people who can set concurrency reservations. Members can view the Concurrency page, and the API returns 403 if a member tries to update a trunk.

No. Inbound calls arrive at whatever speed people dial you and cannot be queued. Use concurrency to plan inbound capacity.

Yes. Every outbound call the platform starts is paced by the same trunk rate: single API calls, campaign dials, automatic retries, and test calls.

Not from the dashboard. Those rates come from your plan because we own the carrier relationship. Contact support to change them.

Check which limit you are hitting. Calls starting slowly but steadily in order points to CPS. Calls starting fast and then stalling points to concurrency. Also compare Total across trunks with any account-level cap your carrier has.