Skip to content

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.

LimitValueNotes
Requests per token30 / secondAcross all methods.
Messages to one private chat1 / secondShort bursts are tolerated; sustained rates are not.
Messages to one group20 / minuteApplies per group, not per member.
Callback answer window20 secondsAnswer a callback_query within this or the user's spinner times out.
Inline query cache300 seconds defaultOverridable 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.

LimitValueNotes
Message text4096 charactersLonger text must be split by you; the API will not do it.
Media caption1024 charactersSend the overflow as a separate message.
Media group size2–10 itemsFewer than 2 is not a group; more than 10 is rejected.
Poll options2–10
Callback data1–64 bytesBytes, not characters. Store state server-side and put a key here, not the state itself.
Deep-link start parameter1–64 characters, A–Z a–z 0–9 _ -

Per account

LimitValueNotes
Bots per account20
Commands per bot100Per scope and language combination.
Mini App preview media12

Webhooks

Delivery is at-least-once: a handler that is slow or returns an error will see the same update again.

LimitValueNotes
Allowed ports443, 80, 88, 8443HTTPS only.
Retry schedule1s, 5s, 30s, 2m, 10mExponential backoff after a failed delivery.
Update retention24 hoursAn update that cannot be delivered within a day is dropped for good.
Mini App protocolshttps onlyhttp 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.