Every Telegram Bot API limit, in one table
Last verified against Telegram Bot API reference
Telegram's limits are scattered across the Bot API reference, the Bot FAQ, the features page and the stickers page. This table collects them with the exact wording and a link to the line that documents each one. Values were verified on 2026-08-20; Telegram changes them occasionally (poll option counts widened recently, and the Paid Broadcasts threshold is stated differently on two official pages), so treat the linked source as authoritative and this page as the index.
Start with the three separate sending throttles, because they are enforced independently and a bot can be inside two while violating the third. The per-chat throttle is roughly 1 message per second to any single chat, with short bursts tolerated. The per-group throttle caps a bot at 20 messages per minute in any one group, regardless of how slowly it sends elsewhere. The global throttle limits bulk notifications to about 30 messages per second across all chats combined, unless Paid Broadcasts is enabled. Exceeding any of them returns HTTP 429 with a retry_after value in seconds; the correct back-off is to sleep exactly retry_after for that request while a single global limiter (one token bucket shared by every worker, with per-chat and per-group budgets layered on top) slows the pipeline, since retrying early typically extends the penalty and per-worker limiters multiply your real rate. Spread large campaigns over 8-12 hours, as the FAQ suggests, rather than sprinting into the ceiling.
Size and length limits (4,096-character text, 1,024-character captions, 50 MB uploads, 20 MB downloads, 64-byte callback_data) are enforced with specific 400 descriptions, and delivery limits (HTTPS-only webhooks on four ports, 24-hour update retention, 1-100 webhook connections) decide whether updates reach you at all. Running your own local Bot API server lifts the file and webhook restrictions but not the rate limits. For the error strings these limits produce, see Telegram Bot API errors; for diagnosing a bot that has gone quiet, see Telegram bot not responding.
Jump to: Sending rate limits · Message text, captions and formatting · File sizes and media geometry · Inline keyboards, callbacks and inline mode · Commands, names and descriptions · Chat metadata, pinning and forum topics · Webhooks and getUpdates · Polls, checklists and stickers · Editing and deleting messages
Sending rate limits
Telegram publishes its sending limits in the Bot FAQ rather than in the API reference, and phrases them as guidance with a hard consequence: go over and you start receiving HTTP 429 with a retry_after value in seconds — the exact handling contract is on the 429 retry after page. The three figures below are enforced independently: a broadcast that stays under 30 messages per second can still be throttled for hitting one group 21 times in a minute. The bulk figure is the one most likely to bite a notification bot at launch, and every failed send to a blocked or deactivated user still spends budget. Paid Broadcasts, enabled in @BotFather, is the only documented way above the bulk ceiling.
| What | Limit |
|---|---|
| Messages to a single chat | About 1 message per second |
| Messages to a single group | 20 messages per minute |
| Bulk notifications (all chats combined) | About 30 messages per second |
| Paid Broadcasts ceiling | Up to 1000 messages per second |
| Paid Broadcasts eligibility | See docs (the API reference says at least 10,000 Stars on the bot's balance; the FAQ says at least 100,000 Stars and 100,000 monthly active users) |
| What you get when you exceed a limit | HTTP 429, description 'Too Many Requests: retry after N', parameters.retry_after = N seconds |
Message text, captions and formatting
All character limits are counted after entities are parsed, so markup characters in MarkdownV2 or HTML do not count but visible text does. Emoji and non-Latin scripts count as one character each. Exceeding the text limit returns Bad Request: message is too long; nothing is sent or truncated, so chunking has to happen on your side, and chunking mid-entity then triggers can't parse entities on the retry. An empty or markup-only text fails the other bound with message text is empty. Captions are a quarter of the text budget, which catches bots that attach long descriptions to images.
| What | Limit |
|---|---|
| Message text (sendMessage, editMessageText) | 1-4,096 characters |
| Media caption (photo, video, document, audio, voice, animation) | 0-1,024 characters |
| Quoted text in reply_parameters.quote | 0-1,024 characters |
| Text sent with a reply keyboard input placeholder | 1-64 characters |
| Messages forwarded or copied in one call | 1-100 message identifiers |
| Album (sendMediaGroup) | 2-10 items |
| Inline result message text (InputTextMessageContent.message_text) | 1-4,096 characters |
File sizes and media geometry
The hosted Bot API enforces different ceilings depending on how a file reaches Telegram. Passing a URL is the most restrictive; uploading with multipart/form-data allows more; reusing a file_id of a file already on Telegram's servers has no size limit at all. Crossing a byte ceiling returns file is too big on both the sending and the getFile side, while image geometry is checked separately and fails with PHOTO_INVALID_DIMENSIONS even for small files. A URL Telegram cannot fetch fails with failed to get HTTP URL content. Running a local Bot API server removes most of these limits (2,000 MB uploads, unlimited downloads) but none of the rate limits.
| What | Limit |
|---|---|
| Send by HTTP URL: photos | 5 MB |
| Send by HTTP URL: other content | 20 MB |
| Upload via multipart/form-data: photos | 10 MB |
| Upload via multipart/form-data: other files | 50 MB |
| Download via getFile | 20 MB |
| Local Bot API server: upload | 2,000 MB |
| Local Bot API server: download | No size limit |
| Photo dimensions (sendPhoto) | Width + height at most 10,000 px; width:height ratio at most 20 |
| Thumbnail for documents/video/audio | JPEG, less than 200 kB, width and height at most 320 px |
| Video note (sendVideoNote) duration | 0-60 seconds (precise duration field) |
Inline keyboards, callbacks and inline mode
Button and query limits are small and strict. The most commonly hit is callback_data, which is limited in bytes rather than characters: exceed 64 and the whole message is rejected with BUTTON_DATA_INVALID; an unparseable button URL fails the same way with BUTTON_URL_INVALID. Callback queries must also be answered promptly — wait too long and answerCallbackQuery returns query is too old while the user's spinner hangs. Telegram does not document a maximum number of buttons or rows in an inline keyboard; keep keyboards small for usability rather than relying on a specific cap.
| What | Limit |
|---|---|
| InlineKeyboardButton.callback_data | 1-64 bytes |
| InlineKeyboardButton.copy_text.text | 1-256 characters |
| Buttons / rows per inline keyboard | Not documented |
| answerCallbackQuery.text | 0-200 characters |
| Inline query text (InlineQuery.query) | Up to 256 characters |
| Results per answerInlineQuery | No more than 50 results |
| Deep-link start parameter | 1-64 characters; only A-Z, a-z, 0-9, _ and - allowed |
| answerCallbackQuery.cache_time | Default 0 seconds |
| answerInlineQuery.cache_time | Default 300 seconds |
Commands, names and descriptions
Bot profile metadata is set through BotFather or the setMy* methods. Each field has a fixed character budget, and commands have a strict character set enforced at registration: anything outside lowercase letters, digits and underscores is rejected by setMyCommands. The username is the one value you cannot change afterwards, so check the length and the required bot suffix before creating the bot; the ID half of the token also encodes the bot, which the token checker can confirm against getMe. Clients cache the command list, so changes can take a while to appear. Command discovery and menu design for support bots is covered on the Telegram chatbot page.
| What | Limit |
|---|---|
| Commands per scope (setMyCommands) | At most 100 commands |
| BotCommand.command | 1-32 characters; lowercase English letters, digits and underscores only |
| BotCommand.description | 1-256 characters |
| Bot name (setMyName) | 0-64 characters |
| Bot description (setMyDescription) | 0-512 characters |
| Bot short description (setMyShortDescription) | 0-120 characters |
| Bot username | 5-32 characters; Latin letters, digits and underscores; must end in 'bot' |
Chat metadata, pinning and forum topics
Chat-level metadata has fixed budgets like bot-profile metadata, but changing it requires rights in the chat: setChatTitle and setChatDescription fail without the appropriate admin permission, and a bot restricted from writing hits have no rights to send a message for posts long before metadata calls matter. Pinning follows the same pattern: allowed everywhere in private chats, admin-right-gated in groups and channels. Forum topic names share the 128-character budget with chat titles. Addressing a chat whose ID changed after a group-to-supergroup upgrade does not fail here but with group chat was upgraded to a supergroup chat, which carries the replacement ID.
| What | Limit |
|---|---|
| Chat title (setChatTitle) | 1-128 characters |
| Chat description (setChatDescription) | 0-255 characters |
| Forum topic name (createForumTopic / editForumTopic) | 1-128 characters |
| Pinning messages (pinChatMessage) | All non-service messages pinnable in private and channel direct messages chats |
Webhooks and getUpdates
Updates are delivered either by long polling (getUpdates) or by webhook, never both: polling while a webhook is set returns 409 Conflict, and a second concurrent poller triggers terminated by other getUpdates request. The hosted API restricts webhook URLs to HTTPS on four ports — violations fail at registration with bad webhook: HTTPS url must be provided or the port-list rejection — and holds undelivered updates for 24 hours. A local Bot API server relaxes the URL, port and connection rules. Delivery-side failures are diagnosed in the webhook debugging guide.
| What | Limit |
|---|---|
| Webhook URL scheme | HTTPS only |
| Webhook ports | 443, 80, 88, 8443 |
| setWebhook.max_connections | 1-100, default 40 |
| setWebhook.secret_token | 1-256 characters; A-Z, a-z, 0-9, _ and - only |
| allowed_updates | List of update type names; empty list = all types except chat_member, message_reaction and message_reaction_count |
| Pending update retention | 24 hours |
| getUpdates.limit | 1-100, default 100 |
| getUpdates.timeout (long polling) | Seconds; default 0 (short polling). No documented maximum |
| Webhook delivery retries | Repeated 'a reasonable amount of attempts' on non-2XX responses |
| Self-signed certificates | Allowed; upload public key via certificate as InputFile |
Polls, checklists and stickers
Interactive content types have their own element counts and lengths. Poll option counts were widened in a recent Bot API update; older guides and library docstrings still say 2-10, and the API now accepts 1-12. Note that a poll, once sent, cannot be edited — only stopped with stopPoll — so an attempt to change one returns message can't be edited. Sticker geometry is published on the separate Stickers page rather than in the API reference, and it differs by format: static, animated (.TGS) and video (.WEBM) each have their own size, duration and frame-rate ceilings. Oversized sticker files fail with file is too big like any other upload.
| What | Limit |
|---|---|
| Poll question | 1-300 characters |
| Poll answer options | 1-12 options |
| Poll option text | 1-100 characters |
| Quiz explanation | 0-200 characters, at most 2 line feeds |
| Poll open_period | 5-2,628,000 seconds |
| Checklist title / task text | Title 1-255, each task 1-100 characters |
| Stickers per set | 120 (200 for emoji sets) |
| Sticker set title | 1-64 characters |
| Static sticker image | PNG or WEBP; one side exactly 512 px, the other 512 px or less (emoji: exactly 100x100) |
| Animated sticker (.TGS) | 512x512 px, at most 64 KB, at most 3 seconds, 60 FPS |
| Video sticker (.WEBM) | One side 512 px, at most 3 seconds, up to 30 FPS, at most 256 KB (emoji: 100x100) |
Editing and deleting messages
Deletion is time-boxed for every bot: after 48 hours a message cannot be deleted by any bot regardless of rights, and the API returns message can't be deleted; deleting something already gone returns message to delete not found instead, which a delete wrapper should treat as success. Editing the bot's own messages has no documented time limit, but editing anything the bot did not send fails with message can't be edited, and re-submitting identical content fails with message is not modified. Beyond those rules, chat permissions decide what is possible, which is why the same call can succeed in one group and fail in another.
| What | Limit |
|---|---|
| deleteMessage age limit | Less than 48 hours old |
| Dice message in private chat | Can only be deleted if sent more than 24 hours ago |
| Editing the bot's own messages | No documented time limit |
| Editing business messages not sent by the bot | Within 48 hours, and only if they have no inline keyboard |
| Paid posts | Cannot be edited; must not be deleted for 24 hours to receive payment |
Telegram guides and tools
Other platforms
Frequently asked questions
How many messages per second can a Telegram bot send?
About 30 per second across all chats for bulk notifications, roughly 1 per second to any single chat, and 20 per minute in a single group, according to the Bot FAQ. Going over returns HTTP 429 with a retry_after value. Paid Broadcasts, enabled in @BotFather, raise the bulk ceiling to 1000 per second for 0.1 Stars per message above the free 30.
What is the maximum Telegram message length for bots?
4,096 characters of text after entities are parsed, for sendMessage and editMessageText. Captions on media are limited to 1,024 characters. Longer content must be split into several messages or sent as a document; the API rejects the whole message with 'Bad Request: message is too long' rather than truncating.
What is the file size limit for Telegram bots?
Uploading via multipart/form-data: 10 MB for photos and 50 MB for other files. Sending by URL: 5 MB for photos and 20 MB for other content. Downloading via getFile: 20 MB. A self-hosted local Bot API server allows uploads up to 2,000 MB and downloads with no size limit. Reusing a file_id already on Telegram has no size limit.
Which ports can a Telegram webhook use?
Only 443, 80, 88 and 8443, and the URL must be HTTPS. setWebhook rejects other ports and plain HTTP. max_connections can be 1-100 (default 40) and secret_token can be 1-256 characters. A local Bot API server lifts the port and scheme restrictions and allows up to 100,000 connections.
How long does Telegram keep undelivered updates?
24 hours. Updates are stored on Telegram's servers until your bot fetches them via getUpdates or receives them on the webhook, but they are not kept longer than 24 hours. After that they are gone. Use drop_pending_updates on setWebhook or deleteWebhook when you do not want a backlog replayed.
What is the limit on callback_data in inline keyboard buttons?
1 to 64 bytes, measured in bytes rather than characters, so non-ASCII text consumes its budget faster. Exceeding it returns Bad Request: BUTTON_DATA_INVALID. Store state on your server and put a short opaque key in the button. Telegram does not document a maximum number of buttons per keyboard.
How many options can a Telegram poll have?
The current Bot API documents 1-12 answer options for sendPoll, each 1-100 characters, with a question of 1-300 characters. Older guides still state 2-10 because that was the previous limit. Quiz explanations are 0-200 characters, and open_period can be 5 to 2,628,000 seconds.
How many commands can a Telegram bot register?
At most 100 commands per scope via setMyCommands. Each command is 1-32 characters of lowercase English letters, digits and underscores, with a 1-256 character description. The bot name is up to 64 characters, the description up to 512, and the short description up to 120.
What is the right back-off strategy when a Telegram bot hits 429?
Read parameters.retry_after from the response and sleep exactly that many seconds before retrying that request; retrying earlier typically extends the penalty. Route all sends through one global rate limiter shared by every worker, with per-chat and per-group budgets layered on top, because Telegram enforces the three throttles independently. Exponential backoff is only appropriate for 502/504 responses, which carry no retry_after.
How long can a Telegram chat title, description or forum topic name be?
setChatTitle accepts 1-128 characters and setChatDescription 0-255. Forum topic names are 1-128 characters on both createForumTopic and editForumTopic. These calls need admin rights in the chat. Bot-profile fields are separate: the bot name is up to 64 characters, the description 512, and the short description 120.
Build on Telegram without tracking every limit yourself
Conferbot paces sends, queues retries and surfaces limit errors as readable status.