pacing
How fast the platform lets an installation send — the three intervals, the rate limiter the core registers from them, and which jobs read each value.
The pacing block is required. Every platform throttles bots differently (Telegram tolerates roughly thirty messages a second with a one-per-second limit into any single chat; a workspace platform may allow one message a second in total), and a connector that hard-codes a sleep is wrong on the next platform. The block makes the numbers data the core reads.
"pacing": {
"min_interval_microseconds": 35000,
"burst": 30,
"per_recipient_interval_microseconds": 1000000
}The fields
All three are required, all integers of at least zero.
| Field | Meaning | Read by |
|---|---|---|
min_interval_microseconds | The shortest gap between any two sends from one installation, whoever they go to. | The broadcast pipeline spaces its sends by it; the queue rate limiter below is derived from it. |
burst | How many sends the platform accepts back to back before the interval has to be honoured. | The queue rate limiter below. |
per_recipient_interval_microseconds | The shortest gap between two sends to the same person. | Jobs that send several messages to one member in a row (the access-code delivery job sleeps it between codes). |
The rate limiter the core registers
When the registry accepts a connector it registers a Laravel rate limiter named connector:<key> (Pacing::limiterName()), sized Pacing::sendsPerSecond(): the lower of burst and one second divided by min_interval_microseconds, never below one send a second. Every paced job the core runs for the connector names that limiter (re-admitting holders after a place is replaced, for one), so Telegram's thirty-a-second and a one-a-second platform are the same code with different data.
| Manifest | Sends per second |
|---|---|
| Telegram: interval 35 000 µs, burst 30 | 28 |
| The fake: interval 1 000 000 µs, burst 1 | 1 |
| A platform with interval 0 and burst 50 | 50 |
Reading it from a connector
ConnectorManifest::$pacing is a Pacing value object with the three fields as public properties. A connector that runs its own loop (a gateway worker draining a queue) reads the intervals from there and never repeats the numbers in code; a connector that only implements Messenger::send() reads nothing, because the core paces the calls.
Pacing is not retry
Pacing keeps the connector under the platform's limit; it does not replace the FailureClassifier. When the platform still answers with a rate-limit response, classify it RateLimited with the platform's retry-after and the core waits exactly that long. Review reads both against the platform's published limits.
How is this guide?
messaging
The platform's message limits — length, buttons, callback data and formatting — and exactly where the core enforces each before a message reaches the connector.
management_commands
The core's in-chat admin command catalogue — every command, what it lets a creator do, and how a connector declares the subset its surface renders.