Outbound send-pacing architecture
Four composable controls shape how fast a campaign sends: the staticthrottle_rate baseline, the time-based ramp_up easing, the
carrier-assigned trust-tier governor ceiling, and closed-loop
adaptive_pacing. Each is a campaign-level opt-in, each narrows the send
rate from a different plane (your config, the clock, the carrier-assigned
tier, and your own delivery receipts), and together they answer the
question operators actually ask: “why is my campaign sending slower than
the throttle I set, and which control decided that?” This page is the
model behind the answer.
Scope and page ownership
This page owns the concept plane of the effective outbound send rate: what each control allows, the fixed order they apply in, the composed-rate rule, the boundary between slowing and stopping, and the reading order that names the control responsible for a slowdown. Configuration recipes live in the guides and are not repeated here:- Trust-tier governor — turning the governor on, its full field table, and when to skip it.
- Adaptive send-pacing — opting in per campaign, the threshold defaults and their valid bands, and API/SDK samples.
- Voice & messaging pricing and throughput —
setting
throttle_rateandramp_up.
The four-control stack and its ordering
The controls apply in a fixed order, and each one narrows what the previous left:throttle_rate— the open-loop baseline. The campaign’s nominal send rate in messages per second. A positive value is your explicit ceiling. Zero, absent, or non-finite is not unlimited: the executor paces at the platform’s default carrier-friendly rate, because the absence of an operator-set rate is not a request for unbounded throughput. When aramp_upprofile is configured, athrottle_rateof 0 instead means “no extra hard ceiling on top of the ramp” — the ramp curve defines the rate.ramp_up— time-based easing. A linear ramp on the baseline: the inter-batch delay starts higher and eases to the nominal rate over the ramp window. Like the throttle it is open-loop; the curve climbs on schedule whether the carrier is accepting the traffic or rejecting half of it.- Trust-tier governor — the hard ceiling. Your brand’s TCR vetting
determines a carrier-assigned throughput class: an AT&T per-campaign
throughput class in messages per minute (converted to a per-second
ceiling) and a T-Mobile per-brand Brand Daily Cap in message parts per
rolling 24 hours. The governor derives both ceilings through the same
resolver the brand throughput endpoint displays, so what it enforces is
what the endpoint shows. Per-field overrides (
mpm,daily_cap) may only pin a lower ceiling than the tier grants; a non-positive value on an axis leaves that axis uncapped. The governor clamps whatever the first two controls produced and never speeds a campaign up. adaptive_pacing— the closed-loop multiplier. The executor periodically re-reads this campaign’s own delivery receipts grouped per carrier (MCCMNC) and folds a pace factor between the configured floor and1into the same effective-rate and inter-batch-delay machinery the governor uses. Healthy traffic keeps the factor at1; a carrier that starts failing or spam-blocking drags it down proportionally.
The composed-rate rule. On every batch, the governor’s and adaptive
pacing’s factors multiply into and clamp the rate that
throttle_rate +
ramp_up produced. The effective send rate is the lowest of what the
four controls allow, never higher than any one of them permits. Two
consequences follow:
- Only the governor can stop the campaign. When the next batch would cross the T-Mobile Brand Daily Cap (parts consumed today + batch size > cap), the loop defers the batch and auto-pauses the campaign rather than oversending; the remaining recipients roll into the next rolling-24h window. The other three only slow: adaptive pacing degrades open and keeps a non-zero floor, and the throttle and the ramp only set ceilings. The authorities on a full halt elsewhere — your credit caps, route circuit-breakers, a manual pause — are untouched by this stack.
- The tightest control wins, per batch. A campaign throttled at 50 MPS under a 20 MPS governor class sends at 20; if adaptive pacing then reports a 0.5 blended factor, the blast sends at 10 until the readings recover.
Adaptive pacing internals
Adaptive pacing scores each destination carrier independently and blends the readings into one campaign factor:- Stress scoring. Per MCCMNC over the rolling
window_minutes(default 15), stress is(failed + blocked) / terminal, where the spam-block subset counts a second time inside the sum: a carrier actively filtering your traffic costs sender reputation more than transient undeliverable churn. - Linear mapping. Stress at or below
healthy_failure_rate(default 0.05) yields factor1; stress at or abovemax_failure_rate(default 0.3) yields themin_pace_factorfloor (default 0.2); between the two the factor interpolates proportionally. Exponential smoothing (smoothing, default 0.5) walks the factor toward each new reading so one noisy window doesn’t slam the rate. - The
min_samplegate. A carrier with fewer terminal messages thanmin_sample(default 20) in-window contributes factor1— a 1-of-1 failure on a tiny carrier is noise, not signal. - Traffic-weighted blend. Each carrier’s factor is weighted by its share of recent terminal traffic, so the destination network carrying most of your volume dominates the blend, and a tiny stressed carrier cannot veto an otherwise healthy blast.
- Open degradation. When the receipt read returns nothing — no rows
yet, a transient read error — the factor is
1. The controller is a reputation optimiser, not a hard stop; a feedback gap never slows a campaign and never halts one.
1, the executor emits a log line naming the
applied factor, the most-stressed carrier’s MCCMNC and its stress rate,
and the number of throttled carriers — the same per-carrier delivery
breakdown the campaign dashboards surface through the
analytics pipeline.
Adaptive pacing reads this campaign’s receipts, so it contributes
nothing where that signal can’t exist or shouldn’t drive the rate: journey
and drip campaigns (contacts enroll one at a time, so there is no batch
volume and no per-window receipt signal), low-volume sends that never
reach min_sample on any carrier, and blasts that must finish inside a
hard window (pacing widens the inter-batch delay when carriers stress).
Those runs are better served by the static throttle_rate plus operator
monitoring.
Interaction with adjacent planes
The four-control stack shapes the rate a campaign offers traffic at. Other planes meter the same traffic from their own vantage, and each interacts with the stack in a specific way:- Per-number warming caps
(sender warming and reputation)
meter the sender identity, not the campaign. Exceeding the trust-tier
phase ceiling returns
DAILY_CAP_EXCEEDED; exceeding the operator-driven growth curve returnsWARMING_QUOTA_EXCEEDEDwith aretry_after. They reject over-cap sends at the number; they do not re-shape the campaign’s rate. The composition runs the other direction: a warming number’s recommended ceiling is an input you fold intothrottle_rateor a governor override, not a term the stack derives. - Route-quality circuit breakers
(outbound route quality)
halt rather than slow. An
opencircuit auto-suspends the degrading carrier route and fails traffic over to your configured channel — a stop-plane control that acts on the route, where pacing acts on the rate. A blast slowed by adaptive pacing and a blast failed over by a breaker are answering different signals (your receipts vs. route health) and can both apply to the same run. - Message-priority traffic lanes (message priority and traffic lanes) meter the account. A campaign’s paced offer rate still feeds the marketing lane’s share of the per-account budget; a blast can be correctly paced by the stack and still be shaped by its lane when the account budget is saturated.
- The cross-campaign allocator (cross-campaign send allocator) plans, the stack reacts. The allocator water-fills each campaign’s volume across the slots of a spread window under your global hourly cap, throttling each campaign’s per-slot share by a sender-reputation pace factor. Once a planned campaign launches, the live four-control stack takes over the rate; the allocator’s schedule is where the run starts, not a ceiling inside the loop.
- Batch dispatch ceilings. The executor meters each batch against the
platform’s per-lane send ceilings, so concurrent lanes never push a
provider into 429 backpressure. These ceilings sit around the campaign
stack, exactly like the account-level lanes: they can shape a burst the
stack cleared, and they report the same
429+Retry-Afterposture as every other throughput ceiling.
Operator observability — the “why is my blast slow” reading order
When a run sends slower than the throttle you set, read the planes in this order; each step names one control or rules it out:- The configured baseline. Check
throttle_rateandramp_upfirst. A zero throttle is the platform default, not unlimited, and a live ramp window means the campaign is still easing toward the nominal rate. - The executor pace log line. If adaptive pacing is engaged and the
factor is below
1, the log line names the applied factor, the most-stressed MCCMNC, its stress rate, and the throttled-carrier count. The per-carrier delivery breakdown in the campaign dashboard (via the analytics pipeline) confirms which destination network is dragging the blend. - The governor verdict. The governor logs the resolved ceilings on every run, and an auto-pause names the exact cap and the consumed count in the pause reason — a paused campaign is explainable, not silent. The brand throughput endpoint shows the same ceilings the governor enforces, so the enforced number and the displayed number never disagree.
- The adjacent planes, if no step above bound. Warming quota errors
(
WARMING_QUOTA_EXCEEDEDwithretry_after, orDAILY_CAP_EXCEEDED) name the per-number ramp; a lane-shaped send reports429withtraffic_lane: "marketing"; per-service and per-number MPS ceilings report429withRetry-After: 1; and a breaker suspension appears in the route-quality state, not in the campaign’s pace at all. The warming dashboard card andGET /api/v1/numbers/:id/warmingsurface the sender-side meter the same way.
Tenant-ownership posture
Every control on this page is opt-in campaign configuration you own. All four live in the campaign’svariables object — the same self-serve
opt-in pattern as the other dispatch governors — and a campaign without
the key sees zero behaviour change, including every campaign created
before the control shipped. There is no platform mandate here: the stack
protects your throughput classes and your sender reputation, and it makes
no compliance claim. Your compliance posture (quiet hours, suppression,
frequency caps) is a separate tenant-owned plane documented under
outbound send gating; the one
platform-owned hard guard, the US TCPA federal voice dialing window,
belongs to that gating plane, not to pacing.
See also
- Trust-tier governor — the configuration guide for the only control in the stack that can stop a run.
- Adaptive send-pacing — the configuration guide for the closed-loop multiplier.
- The cross-campaign send allocator — the planning-time model whose pace factor feeds the allocator, and whose adaptive-pacing primitive is the same loop this page stacks.
- Per-contact channel optimization —
the sibling
campaign.variablesopt-in that shares this page’s dispatch surface. - Sender warming and reputation — the per-number caps that sit in front of the campaign stack.
- Message priority and traffic lanes — the account-level lanes a paced campaign still feeds.
- Outbound route quality and circuit breakers — the stop-plane counterpart to the stack’s slow-plane controls.
- Outbound send gating — the admission chain a paced send still walks.