> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Outbound send-pacing architecture: how the four rate controls compose

> The concept-plane model of a campaign's effective outbound send rate: the static throttle baseline, ramp-up easing, the trust-tier governor hard ceiling, and closed-loop adaptive pacing, the order they apply in, which of them can stop a run, and how to read which one slowed your blast.

# Outbound send-pacing architecture

Four composable controls shape how fast a campaign sends: the static
`throttle_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](https://docs.orbit.devotel.io/guides/trust-tier-governor.md) — turning the governor
  on, its full field table, and when to skip it.
* [Adaptive send-pacing](https://docs.orbit.devotel.io/guides/adaptive-pacing.md) — opting in per campaign,
  the threshold defaults and their valid bands, and API/SDK samples.
* [Voice & messaging pricing and throughput](https://docs.orbit.devotel.io/guides/voice-messaging-pricing-throughput.md) —
  setting `throttle_rate` and `ramp_up`.

Pacing is also a different plane from admission.
[Outbound send gating](https://docs.orbit.devotel.io/concepts/send-gating-and-quiet-hours.md) decides
*whether* a message may leave at all (suppression, quiet hours, frequency
caps, billing posture); this page models *how fast* an admitted campaign
sends. A send the gates refuse was never a pacing decision, and a paced
send still walks every gate at dispatch.

## The four-control stack and its ordering

The controls apply in a fixed order, and each one narrows what the
previous left:

1. **`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 a `ramp_up` profile is configured, a `throttle_rate`
   of 0 instead means "no extra hard ceiling on top of the ramp" — the
   ramp curve defines the rate.
2. **`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.
3. **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.
4. **`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
   and `1` into the same effective-rate and inter-batch-delay machinery
   the governor uses. Healthy traffic keeps the factor at `1`; a carrier
   that starts failing or spam-blocking drags it down proportionally.

| Control | Plane | Reads | Can slow | Can stop |
| - | - | - | - | - |
| `throttle_rate` | open-loop | your campaign config | Yes: sets the nominal ceiling | No |
| `ramp_up` | open-loop | the clock | Yes: eases toward the ceiling | No |
| trust-tier governor | carrier-assigned | the trust tier plus live daily consumption | Yes: clamps to the MPM class | Yes: defers the batch and auto-pauses at the T-Mobile daily cap |
| `adaptive_pacing` | closed-loop | this campaign's DLRs per MCCMNC | Yes: factor between the floor and 1 | No |

**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 factor `1`; stress at or above
  `max_failure_rate` (default 0.3) yields the `min_pace_factor` floor
  (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_sample` gate.** A carrier with fewer terminal messages than
  `min_sample` (default 20) in-window contributes factor `1` — 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.

When the factor drops below `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](https://docs.orbit.devotel.io/concepts/analytics-pipeline.md).

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](https://docs.orbit.devotel.io/concepts/sender-warming-and-reputation.md))
  meter the sender identity, not the campaign. Exceeding the trust-tier
  phase ceiling returns `DAILY_CAP_EXCEEDED`; exceeding the operator-driven
  growth curve returns `WARMING_QUOTA_EXCEEDED` with a `retry_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 into `throttle_rate` or a
  governor override, not a term the stack derives.
* **Route-quality circuit breakers**
  ([outbound route quality](https://docs.orbit.devotel.io/concepts/outbound-route-quality-and-circuit-breakers.md))
  halt rather than slow. An `open` circuit 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](https://docs.orbit.devotel.io/concepts/message-priority-traffic-lanes.md))
  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](https://docs.orbit.devotel.io/concepts/campaign-allocator-model.md))
  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-After` posture 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:

1. **The configured baseline.** Check `throttle_rate` and `ramp_up` first.
   A zero throttle is the platform default, not unlimited, and a live ramp
   window means the campaign is still easing toward the nominal rate.
2. **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](https://docs.orbit.devotel.io/concepts/analytics-pipeline.md)) confirms which
   destination network is dragging the blend.
3. **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](https://docs.orbit.devotel.io/guides/10dlc-rejections-and-revet.md)
   shows the same ceilings the governor enforces, so the enforced number
   and the displayed number never disagree.
4. **The adjacent planes, if no step above bound.** Warming quota errors
   (`WARMING_QUOTA_EXCEEDED` with `retry_after`, or `DAILY_CAP_EXCEEDED`)
   name the per-number ramp; a lane-shaped send reports
   `429` with `traffic_lane: "marketing"`; per-service and per-number MPS
   ceilings report `429` with `Retry-After: 1`; and a breaker suspension
   appears in the route-quality state, not in the campaign's pace at all.
   The warming dashboard card and `GET /api/v1/numbers/:id/warming`
   surface the sender-side meter the same way.

The stack composes downward, so the responsible control is always the
tightest one currently binding — the reading order above lists the planes
in the order they most commonly bind.

## Tenant-ownership posture

Every control on this page is **opt-in campaign configuration you own**.
All four live in the campaign's `variables` 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](https://docs.orbit.devotel.io/concepts/send-gating-and-quiet-hours.md); 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](https://docs.orbit.devotel.io/guides/trust-tier-governor.md) — the configuration
  guide for the only control in the stack that can stop a run.
* [Adaptive send-pacing](https://docs.orbit.devotel.io/guides/adaptive-pacing.md) — the configuration
  guide for the closed-loop multiplier.
* [The cross-campaign send allocator](https://docs.orbit.devotel.io/concepts/campaign-allocator-model.md) —
  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](https://docs.orbit.devotel.io/concepts/channel-optimization-model.md) —
  the sibling `campaign.variables` opt-in that shares this page's dispatch
  surface.
* [Sender warming and reputation](https://docs.orbit.devotel.io/concepts/sender-warming-and-reputation.md) —
  the per-number caps that sit in front of the campaign stack.
* [Message priority and traffic lanes](https://docs.orbit.devotel.io/concepts/message-priority-traffic-lanes.md) —
  the account-level lanes a paced campaign still feeds.
* [Outbound route quality and circuit breakers](https://docs.orbit.devotel.io/concepts/outbound-route-quality-and-circuit-breakers.md) —
  the stop-plane counterpart to the stack's slow-plane controls.
* [Outbound send gating](https://docs.orbit.devotel.io/concepts/send-gating-and-quiet-hours.md) — the
  admission chain a paced send still walks.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.