Rate limits
Limits keep one bot from crowding out the others and from flooding people. They depend on the bot's tier: new for its first 14 days, then standard, or verified with the blue check (getMe shows it).
Per bot#
| Limit | new | standard | verified |
|---|---|---|---|
| API calls per second | 10 | 30 | 60 |
| Messages per second, all chats together | 5 | 30 | 60 |
| Messages per chat | 1 per second, bursts of 3 (3 in any 3-second window) | ||
| Messages per group or channel per minute | 20 | 20 | 40 |
| Unsolicited 1:1 messages per person per day | 3 | 10 | 50 |
| Rooms joined per day | 10 | 50 | 500 |
| Upload volume per UTC day | 200 MB | 1 GB | 5 GB |
| Moderation actions per room per minute | 30 | ||
Command-list changes (setMyCommands + deleteMyCommands) | 10 per minute | ||
Key proposals (setMyEncryptionKey) | 5 per hour | ||
setWebhook | 20 per hour per bot, 40 per hour per owner; 30 failed challenges per destination host per hour | ||
Concurrent getUpdates | 1 (a second one answers 409 conflict) | ||
“Messages” includes media and encrypted replies. Unsolicited messages are 1:1 messages to someone who has not written to the bot, pressed its button or started it in the last 24 hours; past the cap the answer is 403 unsolicited_limit, not 429. “Rooms joined per day” is checked when an admin adds the bot; the admin sees the refusal.
Platform-wide#
- Global ceiling: all bots together send at most 300 messages a second. Hitting it answers 429 to whichever bot sends next. It is a safety valve, not something bots should ever reach.
- Long-poll slots: a limited number of waiting
getUpdatescalls exist at a time. When none is free,getUpdatesreturns[]at once withRetry-After: 2. - Edge limits (in front of the API): 60 requests a second per token with bursts of 60, 120 a second per client address, and 10 concurrent connections per token.
- Failed authentication: 30 failed tokens a minute from one address for one bot number, and 600 a minute from one address in all (an IPv6 address counts by its /64). Past that, the address gets 429 before any token is checked. A token that worked in the last minute is never held back by this.
Limits on people (for context)#
- A person can press at most 10 bot buttons in 10 seconds.
- A person receives at most 10 push notifications per bot per hour; further messages arrive silently.
- In encrypted groups, a person can address bots at most 20 times a minute and 300 times a day; a bot's answers to one person are limited to 50 a day.
- A person can report bots at most 5 times an hour.
How a 429 looks#
HTTP/1.1 429 Too Many Requests
Retry-After: 3
X-Request-Id: 01JB2H9M4T7Q2V8X5C1N6R3K0W
{"ok":false,"error":{"code":"rate_limited","message":"Too many requests","retry_after":3,"parameter":null},
"request_id":"01JB2H9M4T7Q2V8X5C1N6R3K0W"}
Wait retry_after seconds before retrying that call. An edge limit answers the same shape with retry_after: 1 but without request_id. The SDKs wait and retry for you, up to a maximum you choose.
Spread bulk sends over time rather than retrying in a tight loop: a bot that keeps hitting limits gets slower, not faster.