Pacing and retries
How campaign concurrency, carrier rate limits, predictive pacing, retry priority, and abandon-rate braking work together in the Ori dialler — and which campaign fields control them.
When a campaign is running, the Ori dialler decides — every couple of seconds — how many fresh calls to launch. It balances filling your bots against not ringing more customers than you can actually talk to. This page explains the layers that limit dialling pressure, how predictive pacing works, the order in which contacts are dialled, and the safety brake that protects you from abandoning calls.
It is a conceptual page. The fields mentioned here are set on the Dialler Config step of the campaign wizard — see Create a campaign for the field-by-field walkthrough — and the live numbers they produce are shown on the campaign monitor.
What limits dialling pressure
How fast a campaign dials is never decided by a single number. Several independent limits sit in front of every new call, and the smallest available limit always wins.
| Layer | What it is | Where you set it |
|---|---|---|
| Campaign concurrency (seats) | The maximum number of simultaneous connected conversations the campaign is allowed to hold. This feeds the pacing formula. | Concurrency Limit on the campaign wizard |
| Carrier CPS | A per-carrier ceiling on how many new calls per second may be placed on a phone line. Separate from seats. | Carrier settings — see Carriers |
| Time window | New calls only launch inside the campaign's local calling hours and on its working days. | Time Window and Working Days on the campaign wizard |
| Fleet availability | The dialler only attaches an answered call when there is a free voice worker to take it. | Fleet capacity — see Fleet |
| Telephony capacity | The carrier and the LiveKit transport must accept the volume of calls being placed. | Carrier / transport configuration |
| Circuit breakers | If a dependency keeps failing, the backend temporarily stops sending it traffic so the failure does not spread. | Automatic — no setting |
Concurrency (seats) and carrier CPS are the two limits you control most directly, and they protect different things. Seats protect your bots and fleet from being overwhelmed. CPS protects the phone line from placing more calls per second than the carrier permits. Raising one does not raise the other.
Seats versus carrier CPS
These two limits are easy to confuse because both cap call volume, but they work on different units.
Concurrency (seats)
Counts conversations in progress. If the limit is 50, the campaign will never hold more than 50 live, connected calls at once. Ringing calls do not count against this — only calls that have been answered and handed to a bot.
Carrier CPS
Counts new calls started per second. A token-bucket limiter releases dials at the carrier's allowed rate. Even if the seat maths asks for a burst of calls, they are released no faster than the carrier permits.
A useful way to picture it: seats are how many chairs are in the room, and CPS is how fast people are allowed in through the door. You can have plenty of empty chairs but still be held at the door if the carrier's per-second rate is the tighter limit.
Ringing is not counted against concurrency. It is self-limited by the carrier CPS rate and by how long calls are allowed to ring. This is deliberate — it lets the dialler keep a small pool of calls ringing so that seats stay full as conversations end, without over-counting calls that have not connected yet.
How predictive pacing works
Simply dialling one number for every free seat wastes time: by the time a call rings, goes unanswered, and is given up, the seat has been idle. To keep bots busy, the dialler over-dials slightly — it places a few more calls than there are free seats, betting (from recent history) that some will not be answered.
The dial rate is driven by an industry-standard predictive formula:
target_dial_rate = min( carrier_cps_cap , seats / (AHT × answer_rate) )- seats — the campaign's concurrency limit, capped at the fleet capacity actually available.
- AHT — average handle time: how long connected calls have been lasting, in seconds.
- answer_rate — the rolling share of dialled calls that get answered.
The result is then turned into a small pool of ringing calls, sized to keep seats fed across one ring cycle. As answer rate and handle time drift over the campaign, the dialler continuously re-reads them and adjusts the rate — you do not tune this by hand.
Cold start
A brand-new campaign has no answer-rate history, so over-dialling early would be guessing. Until the campaign has roughly 20 completed calls, the dialler does not over-dial. It simply fills free seats one-for-one. Once enough calls have completed to give a stable answer-rate signal, the predictive formula takes over.
Tip
This is why a fresh campaign can look slow for its first minute or two. That is the cold-start period building a baseline, not a fault. Watch the Dials/sec and Answer Rate figures on the monitor climb as the campaign warms up.
Abandon-rate braking
The predictive formula handles the average case. A separate feedback loop handles spikes — moments when too many answered calls have no free seat to take them, which the customer experiences as dead air or an abrupt drop. That is an abandoned call, and regulators and clients both care about keeping the rate low.
The brake only engages once there is a meaningful sample (around 30 answered calls), so early noise does not trip it.
| Abandon rate | What the dialler does |
|---|---|
| At or below 3% | No brake. Pacing runs normally. |
| Above 3% and up to 5% | Eases off — scales the dial rate down toward the 3% target. |
| Above 5% | Hard brake — the dial rate is halved immediately. |
You can read the live Abandon Rate in the metrics strip on the campaign monitor. If you see it climbing toward the upper band, the dialler is already pulling back on its own; you do not need to intervene unless it stays high, in which case lower the Concurrency Limit.
A short, clean connect that the bot handles is not an abandon. An abandon is specifically an answered call that found no seat to take it. See Dispositions for how the different outcomes are recorded.
Lease priority — what gets dialled first
Within a single campaign, not all due contacts are equal. The dialler leases work in a strict order so that every contact is reached at least once before any number is retried.
Callbacks
Contacts the customer explicitly asked to be called back, whose scheduled time has arrived. These come first because the customer is expecting the call. Requires callback detection — see Callbacks.
Pending
Fresh contacts that have never been dialled. These come before retries so the campaign makes a complete first pass over the whole list before circling back to anyone.
Retries
Contacts from a previous attempt whose retry delay has elapsed and which are eligible to be tried again.
This ordering is why the monitor shows progress in passes. The first pass works through every pending contact; later passes pick up the retries that have since become due. A callback that falls due will jump ahead of both.
Retry rules
When a call does not reach the customer, whether it is tried again — and how many times — is governed by the retry settings on the campaign wizard. These are the fields, with their exact labels and defaults.
| Field | What it does | Default / validation |
|---|---|---|
| Max Attempts | The maximum number of times a single contact will be dialled, across the first attempt and all retries. | Defaults to 3 if left blank or set below 1. |
| Retry Delay (minutes) | How long to wait after a failed attempt before the contact becomes eligible for the next retry. | Defaults to 30 if left blank or set below 1. |
| Retry on System Dispositions | Checkboxes for the system outcomes that should trigger a redial: no_answer, rejected, RNR, error, timeout. Tick the ones you want retried. | Optional. |
| Custom Retry Dispositions | A comma-separated list of business disposition names that should also trigger a redial, for example callback_requested, not_available. | Optional. Parsed into a list when you save. |
A contact stops being retried as soon as any of these is true: it reaches a final outcome you did not mark for retry, it hits Max Attempts, or one of the redial-control rules below cancels its remaining attempts.
Only list a value under Custom Retry Dispositions if your bot's post-call analysis reliably produces that exact string. A name that never appears as a disposition simply never triggers a retry — there is no error, the redial just silently never happens.
Redial controls
Two optional rules let you fine-tune retries based on how long the last connected call lasted. They are useful when "the call connected" does not always mean "the customer was actually reached".
If you enable both rules, keep the stop-after threshold at or above the redial-under threshold. If the stop threshold is the lower of the two, connects that fall between the two values are ambiguous — and in that case the stop rule wins, so the contact will not be redialled. The wizard shows an inline warning when your thresholds are set this way; adjust them until the warning clears.
Time windows
New calls only launch inside the campaign's calling window. The window is defined by three fields on the wizard — a Start time, an End time (both in 24-hour HH:MM format, defaulting to 09:00 and 18:00), and a Timezone — together with the Working Days checkboxes (all seven days by default).
Always set the timezone to the customers' legal, contactable timezone. For India campaigns this is normally:
Asia/KolkataThe dialler will not start new calls outside the window or on a non-working day, but a conversation already in progress when the window closes is allowed to finish naturally. How the campaign behaves at the window edge also depends on its mode:
- Single Day campaigns stop at the cutoff and do not resume.
- Multi Day campaigns stop dialling at the cutoff and pick up again on the next working day.
The campaign monitor shows a "Paused — Outside time window" indicator when a running campaign is idle only because it is currently outside its window.
Practical concurrency guidance
Concurrency is the one pacing number you set directly, so set it with care. The CSV row count is not a target — a list of 500,000 contacts does not mean you set concurrency to 500.
Start low on the first live run
Begin a new campaign with a modest concurrency so you can watch behaviour before scaling up.
Increase gradually after a stable test
Once a test run looks healthy — answer rate steady, abandon rate low, recordings and results arriving — raise concurrency in steps.
Watch for the warning signs
Back off if you see no-answer or rejected outcomes spiking, repeated errors, the abandon-rate brake engaging, fleet capacity running out, or call results failing to push to your CRM.
Your concurrency must fit within everything downstream of it: the fleet, the carrier's phone lines and CPS, and what your customers and client will tolerate. The smallest of those is your real ceiling.
When to pause
Pause a running campaign — using the Pause control on the campaign list or detail page — as soon as you suspect something is wrong, then fix it before resuming:
- The wrong bot or configuration was selected.
- The CSV variables are wrong, so the bot greets people incorrectly.
- A large share of calls fail with the same telephony error.
- Customers report the wrong script or language.
- Fleet health looks unstable.
- Call results are repeatedly failing to reach your CRM.
Pausing stops new dials immediately. Calls already connected are allowed to finish, and you can resume from exactly where you left off once the issue is resolved.