Telegram Bot API Limits: Rate Limits, 429 Errors, File Sizes and Message Length
Telegram Bot API rate limits look simple on paper: about 1 message per second in a single chat, 20 messages per minute in a group, and roughly 30 messages per second across all chats. Exceed them and the API answers 429 Too Many Requests with a retry_after value. This page collects the Telegram Bot API limits in one place (sending rates, paid broadcasts, file sizes, text lengths and updates) with code that keeps your bot inside them.
Telegram Bot API rate limits for sending messages
The official Bots FAQ lists these limits for regular, free sending:
| Scope | Limit | Notes |
|---|---|---|
| One chat | β 1 message per second | Short bursts are tolerated, then 429 errors start. |
| One group | 20 messages per minute | Counted per group chat. |
| Bulk notifications | β 30 messages per second | Up to 1000 per second with paid broadcasts. |
Treat these numbers as guidelines rather than a contract. Telegram notes that limits may change, and flood limits are not raised in the test environment (they can even be stricter there). Code that respects retry_after survives changes that would break a hardcoded "30".
429 Too Many Requests and retry_after
When you hit a flood limit, the response looks like this:
{
"ok": false,
"error_code": 429,
"description": "Too Many Requests: retry after 17",
"parameters": {"retry_after": 17}
}
retry_after is the number of seconds left before the request can be repeated. Wait at least that long, then send the same request again; immediate retries only prolong the block. A Python helper:
import time
import requests
API = "https://api.telegram.org/bot123456789:AAEexampleTokenReplaceWithYours"
def call(method, max_attempts=5, **params):
for _ in range(max_attempts):
r = requests.post(f"{API}/{method}", json=params, timeout=30).json()
if r["ok"]:
return r["result"]
if r["error_code"] != 429:
raise RuntimeError(f'{r["error_code"]}: {r["description"]}')
time.sleep(r.get("parameters", {}).get("retry_after", 1) + 0.5)
raise RuntimeError("still rate limited, giving up")
call("sendMessage", chat_id=123456789, text="Hello")
The same logic in JavaScript:
const API = "https://api.telegram.org/bot123456789:AAEexampleTokenReplaceWithYours";
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function call(method, params, maxAttempts = 5) {
for (let i = 0; i < maxAttempts; i++) {
const res = await fetch(`${API}/${method}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(params),
});
const data = await res.json();
if (data.ok) return data.result;
if (data.error_code !== 429) throw new Error(data.description);
await sleep(((data.parameters?.retry_after ?? 1) + 0.5) * 1000);
}
throw new Error("still rate limited");
}
Throttle broadcasts with a queue
Retries fix single requests. For newsletters and notifications you have to pace the sending itself, for example at a global rate a little below 30 messages per second:
def broadcast(chat_ids, text, per_second=25):
for chat_id in chat_ids:
try:
call("sendMessage", chat_id=chat_id, text=text)
except RuntimeError as e:
print(chat_id, e) # 403: the user blocked the bot, drop them
time.sleep(1 / per_second)
In production, run this in a background worker, keep a per-chat timestamp so no chat gets more than one message per second, and drop chats that return 403 instead of retrying them. Without paid broadcasts, Telegram recommends spreading large mailings over longer intervals, such as 8β12 hours.
Paid broadcasts: up to 1000 messages per second
If 30 messages per second is not enough, enable paid broadcasts in @BotFather and pass "allow_paid_broadcast": true to send methods such as sendMessage, sendPhoto or sendMediaGroup. The bot can then broadcast up to 1000 messages per second. Every message above the free 30 per second costs 0.1 Telegram Stars from the bot's balance, and only successfully broadcast messages are charged. Eligibility requires a minimum Stars balance (the Bots FAQ also mentions an audience threshold), so check the official docs for the current numbers before you plan around it.
Telegram bot file size limits
| Operation | Limit |
|---|---|
Upload a file with multipart/form-data | 50 MB |
| Upload a photo | 10 MB; width + height β€ 10000, aspect ratio β€ 20 |
| Send a photo by HTTP URL | 5 MB |
| Send other files by HTTP URL | 20 MB (sendDocument by URL works only for .PDF and .ZIP) |
Download with getFile | 20 MB; the download link is valid for at least 1 hour |
Resend by file_id | No size limit |
A local Bot API server lifts the two biggest restrictions: uploads up to 2000 MB and downloads without a size limit, plus webhooks over plain HTTP on any port. Call logOut before you point the bot at your own server. To check a file before downloading, call getFile in the Bot API Tester and look at file_size and file_path.
Message length and other content limits
| Item | Limit |
|---|---|
| Message text | 1β4096 characters after entity parsing |
| Media caption | 0β1024 characters |
Rich message (sendRichMessage) | 32768 UTF-8 characters, 500 blocks, 50 media, 20 table columns |
callback_data | 1β64 bytes |
| Media group | 2β10 items |
| Inline query answer | Up to 50 results |
answerCallbackQuery text | 0β200 characters |
setMyCommands | 100 commands; command 1β32 characters, description 1β256 |
Deep link start parameter | Up to 64 characters: A-Z a-z 0-9 _ - |
Mini App sendData | Up to 4096 bytes |
callback_data is counted in bytes, and characters outside ASCII take 2β4 bytes each in UTF-8, so store a short id in the button and keep the details in your database. Texts longer than 4096 characters must be split, preferably on line breaks:
def split_text(text, limit=4000): # a little below 4096 to be safe
parts, current = [], ""
for line in text.splitlines(keepends=True):
if current and len(current) + len(line) > limit:
parts.append(current)
current = ""
while len(line) > limit:
parts.append(line[:limit])
line = line[limit:]
current += line
if current:
parts.append(current)
return parts
Updates and webhook limits
- Incoming updates are kept on Telegram's servers for up to 24 hours until your bot receives them.
getUpdatesreturns 1β100 updates per call (limit, default 100). Usetimeoutfor long polling and confirm updates withoffset= lastupdate_id+ 1.getUpdatesdoesn't work while a webhook is set (409 Conflict) until you calldeleteWebhook.setWebhookacceptsmax_connections1β100 (default 40) and ports 443, 80, 88 and 8443 only. A local Bot API server allows up to 100000 connections and any port.
How to stay under Telegram Bot API limits
- Send everything through one queue with a global rate below 30 per second and at most one message per second per chat.
- Show progress by editing one message with
editMessageTextinstead of posting many new ones. - Resend media by
file_idrather than uploading it again. - Honor
retry_after, and never retry 403 errors. - Pass
allowed_updatesso you receive only the update types you actually handle.
Related guides: sending messages with the Bot API covers formatting and per-message errors, setting up a webhook explains receiving updates at scale, and what's new in Bot API 10 introduces rich messages and their limits.
Frequently asked questions
What is the Telegram Bot API rate limit?
Telegram's Bots FAQ gives three numbers: avoid more than 1 message per second in a single chat, send no more than 20 messages per minute in a group, and about 30 messages per second for bulk notifications. Exceeding them returns 429 Too Many Requests.
How do I fix 429 Too Many Requests in Telegram?
Read parameters.retry_after from the error, wait that many seconds and repeat the same request. To stop hitting the limit, send through a queue that paces messages per chat and globally.
What is the Telegram bot file size limit?
Bots can upload files up to 50 MB (photos up to 10 MB) and download files up to 20 MB with getFile. Sending by URL is limited to 5 MB for photos and 20 MB for other files. A local Bot API server allows uploads up to 2000 MB and downloads without a size limit.
How long can a Telegram bot message be?
A text message can contain 1β4096 characters after entity parsing and a media caption 0β1024 characters, so longer texts must be split. Rich messages (Bot API 10.1+) allow up to 32768 UTF-8 characters.
How can a Telegram bot send more than 30 messages per second?
Enable paid broadcasts in @BotFather and pass allow_paid_broadcast: true. The bot can then send up to 1000 messages per second; every message above the free 30 per second costs 0.1 Telegram Stars, charged only for successful broadcasts.
How long does Telegram keep updates for a bot?
Undelivered updates are stored for up to 24 hours. getUpdates returns at most 100 updates per call; confirm them by passing offset equal to the last update_id + 1.
Related guides
How to Create a Telegram Bot: Step by Step with BotFather and Python
How to create a Telegram bot step by step: register it with @BotFather, get the token, test it with getMe and send a first message with curl or Python.
Telegram Bot API 10.0β10.3: Rich Messages, Ephemeral Messages, Guest Mode and More
What's new in Telegram Bot API 10.0β10.3: guest mode, rich messages, streamed drafts, ephemeral messages, join request queries, with JSON examples.
How to Send a Message with the Telegram Bot API (sendMessage)
Telegram Bot API send message guide: sendMessage with curl, Python and JavaScript, HTML and MarkdownV2 formatting, inline buttons and error fixes.
Telegram Bot Token: How to Get It, Find It Again, Check It and Keep It Safe
Telegram bot token guide: get one from @BotFather, find the token of an existing bot, check it with getMe, revoke a leaked token and store it safely.
How to Set Up a Telegram Bot Webhook: setWebhook, Secret Token and Troubleshooting
Set up a Telegram bot webhook: setWebhook URL requirements, secret_token header check, getWebhookInfo debugging, deleteWebhook and fixes for n8n.
How to Get a Telegram Chat ID for a User, Group, Channel or Topic
How to get a Telegram chat ID for a user, group, supergroup, channel or forum topic with getUpdates, plus fixes for an empty result and 409 Conflict.
How to Test a Telegram Mini App: From Browser Mock to Real Telegram
Test a Telegram Mini App step by step: browser mock mode, localhost via HTTPS tunnel, test environment, DevTools per platform, initData validation.