Rate limits and capacity
- Updated
- Reading time
- 3 min
- Level
- intermediate
There are two kinds of limit in Revoye and they behave differently: ours protect the service, and yours protect your provider accounts. Confusing them is the commonest source of "why is my integration slow" tickets.
Revoye's ingress limits
Requests per minute, per API key. Exceeding them returns 429 RATE_LIMITED with a Retry-After
header. Honour the header.
| Limit | Covers | |
|---|---|---|
| Writes | 600 / minute | POST /v1/completions, POST /v1/chat/completions, DELETE /v1/completions/{id} |
| Reads | 1 200 / minute | GET /v1/completions/{id}, GET /v1/status, GET /v1/models |
Per key rather than per account, so one integration in a retry loop cannot take the production key beside it down with it. Rotate a key and the replacement starts with a fresh budget.
This limit is about request rate, not work volume. It is difficult to hit accidentally with real
prompts — a prompt takes tens of seconds to run, and ten enqueues a second sustained is far more
than any fleet of agents can consume — and easy to hit by polling GET /v1/status in a loop. If you are seeing 429, look at your polling before you look at your prompts.
Your own hourly limits
Set in the dashboard, at three levels:
| Level | Protects |
|---|---|
| Per agent | One agent, one provider account, from being hammered |
| Per provider | Everything on that provider together |
| Global | All your providers at once |
When one is reached, the router stops dispatching to whatever it covers. The job does not fail — it
waits, or goes to another eligible agent. 503 PROVIDER_RATE_LIMITED surfaces only when you asked
not to wait, so a caller who wanted an immediate answer gets an explanation rather than a hang.
GET /v1/status reports rate_limit_per_hour and used_this_hour for each provider, so your own
code can see how close it is.
Setting them sensibly
These caps exist because an account that suddenly makes hundreds of requests an hour does not look like a person using a chat product. Set them below whatever the provider would consider unusual for your account, and leave headroom. Revoye cannot tell you what that number is — no provider publishes one — which is exactly why the control is yours and the default is conservative.
Sizing your fleet
Throughput is agents, not bandwidth.
prompts per hour ≈ agents × (3600 / average seconds per prompt)At 45 seconds per prompt, one agent is roughly 80 prompts an hour. Three agents, roughly 240 — if your own hourly caps allow it, and if the machine can keep three agents working at once.
The constraints, in the order they usually bind:
- Your hourly caps.
- The number of agents you have created.
- The machine's memory — every agent uses some of it.
- What each provider account tolerates.
Diagnosing a slow integration
| Symptom | Cause | Fix |
|---|---|---|
queue.depth climbing, agents.idle at zero | Saturated | More agents, or fewer prompts |
queue.oldest_queued_at far in the past, devices.online: 0 | The machine is asleep | Turn it on; or use webhooks so it does not matter |
Frequent PROVIDER_RATE_LIMITED | Your own cap is the constraint | Raise it deliberately, or spread across more providers |
Frequent 429 RATE_LIMITED | You are polling | Poll less; use webhooks |
attempts > 1 on most jobs | Agents are timing out | Check Revoye Desk; raise timeout_ms for long prompts |
Other limits
| Prompt | 100 000 characters |
messages on /v1/chat/completions | 256 messages, each ≤ 100 000 characters, flattening to ≤ 100 000 characters |
| Request body | 1 MiB |
| Queued jobs per account | 1 000 |
| Per-attempt timeout | 5 000–600 000 ms (default 180 000) |
| Whole-job deadline | 10 000–3 600 000 ms (default 900 000) |
metadata | 4 KiB |
The public API has no list endpoints. Keep your own index: store each job id alongside your record when you submit, and query your own database rather than trying to enumerate jobs through Revoye.