Rate limits
Palloo limits how fast a bot can call the API. Here is what the limits are, how a refused request looks and how to back off.
On this page
How limits work
Every limit is a bucket with a burst and a refill rate: a bot can make the burst's worth of calls at once, and then one more each time the refill interval passes. Limits apply per bot (by its ID), per webhook, or per client address, as listed below.
A refused request
A request over a limit answers:
HTTP/1.1 429 Too Many Requests
Retry-After: 2
Content-Type: application/json
{"error": {"code": "rate_limited", "message": "too many attempts, try again later"}}
Retry-After is the number of whole seconds to wait (at least 1). Wait at least that long before you send the same kind of request again.
Palloo does not send X-RateLimit-* headers or bucket IDs, and a 429 has no retry_after or global fields in its body. Pace your bot by the numbers below, and treat Retry-After as the authority when you are refused.
Some limits that protect accounts are counted in a shared store. If that store cannot be reached, those operations answer 503 with the code rate_limiter_unavailable and a Retry-After header instead of skipping the limit. Retry after the delay.
Limits for bots
| What | Burst | Then |
|---|---|---|
| Every authenticated request, per bot | 50 | 1 every 20 ms (50 a second) |
| Sending and editing messages, and answering interactions with a message, completing them and following up, per bot | 20 | 1 every 250 ms (4 a second) |
| Marking messages or servers read, per bot | 30 | 1 every 500 ms |
| Opening a DM, per bot | 10 | 1 every 10 seconds |
| Registering commands, per bot | 50 | 1 every 2 seconds |
| Changing a server's structure (channels, roles, overwrites and similar), per caller | 30 | 1 a second |
| The same, per server, for everyone together | 60 | 1 a second |
| Starting a thread, per caller | 10 | 1 every 30 seconds |
| Starting a thread, per channel | 30 | 1 every 2 seconds |
| Changing threads, per caller | 30 | 1 a second |
| Typing indicators, per caller | 10 | 1 a second |
| Upload slots, per caller | 30 | 1 every 2 seconds |
| Finalizing uploads, per caller | 20 | 1 every 500 ms |
The per-bot limits and the whole-request limit are counted separately by each server process, and the hosted instance may run several. Do not rely on getting more than the numbers above.
Webhooks
| What | Burst | Then |
|---|---|---|
| Posts, per webhook | 5 | 1 a second |
| Posts, per client address | 60 | 1 a second |
| Posts with files, per webhook | 5 | 1 every 12 seconds |
Gateway
| What | Burst | Then |
|---|---|---|
| Connection attempts, per client address | 60 | 1 a second |
update_presence, per connection |
5 | 1 every 10 seconds; extra updates are combined and applied later |
subscribe_presence, per connection |
5 | 1 every 2 seconds |
request_online_members, per connection |
10 | 1 every 500 ms |
A connection that falls 256 events behind is closed with 4006. See Gateway for connection limits.
Handling 429 well
- Read
Retry-Afterand wait at least that long. Add a little random delay if many workers share a bot. - Queue messages per bot instead of sending them all at once. Sending in bursts of 20 and then 4 a second never gets refused.
- Do not retry a refused request in a tight loop: every attempt counts.
- Prefer one request that does more (listing members a page at a time, for example) over many small ones.