Appearance
Limits
Every number on this page is a specified target, not an observed one — the gateway that would enforce them is not deployed. They are published so you can design within them, and they may still move before launch.
Not enforced yet
The gateway is not deployed, so nothing on this page is currently applied to anything. See implementation status.
Rate limits
Exceeding any of these returns 429 with parameters.retry_after. Sleep for exactly that long. Retrying early extends the window rather than shortening it, and a tight retry loop is indistinguishable from an attack.
| Limit | Value | Notes |
|---|---|---|
| Requests per token | 30 / second | Across all methods. |
| Messages to one private chat | 1 / second | Short bursts are tolerated; sustained rates are not. |
| Messages to one group | 20 / minute | Applies per group, not per member. |
| Callback answer window | 20 seconds | Answer a callback_query within this or the user's spinner times out. |
| Inline query cache | 300 seconds default | Overridable per response with cache_time. |
Message content
Lengths are counted in UTF-16 code units — the same unit entity offsets use. An emoji costs 2. Splitting a long message on a byte boundary will cut a character in half.
| Limit | Value | Notes |
|---|---|---|
| Message text | 4096 characters | Longer text must be split by you; the API will not do it. |
| Media caption | 1024 characters | Send the overflow as a separate message. |
| Media group size | 2–10 items | Fewer than 2 is not a group; more than 10 is rejected. |
| Poll options | 2–10 | |
| Callback data | 1–64 bytes | Bytes, not characters. Store state server-side and put a key here, not the state itself. |
| Deep-link start parameter | 1–64 characters, A–Z a–z 0–9 _ - |
Per account
| Limit | Value | Notes |
|---|---|---|
| Bots per account | 20 | |
| Commands per bot | 100 | Per scope and language combination. |
| Mini App preview media | 12 |
Webhooks
Delivery is at-least-once: a handler that is slow or returns an error will see the same update again.
| Limit | Value | Notes |
|---|---|---|
| Allowed ports | 443, 80, 88, 8443 | HTTPS only. |
| Retry schedule | 1s, 5s, 30s, 2m, 10m | Exponential backoff after a failed delivery. |
| Update retention | 24 hours | An update that cannot be delivered within a day is dropped for good. |
| Mini App protocols | https only | http URLs are refused, including on localhost. |
Staying inside them
Queue per chat rather than globally. Most bots that hit a limit are not sending too much overall — they are sending a burst to one chat while idle everywhere else. A per-chat queue with a small delay smooths that out without slowing the bot down.
Treat 429 as backpressure, not as an error to log and move past. Honour retry_after exactly, and let it slow the queue rather than retrying in place.