Telegram Bot Rate Limits Explained: 429 Errors, retry_after and a Scheduler Queue That Stays Under (2026)
What are Telegram's bot rate limits, and what should a scheduler do on a 429?
Telegram's Bots FAQ gives three numbers: in a single chat, avoid more than about one message per second; in a group, a bot can't send more than 20 messages per minute; and for bulk notifications, a bot can't broadcast more than about 30 messages per second unless it enables paid broadcasts. Go over them and the Bot API answers with HTTP 429 and an error object that can include retry_after: the number of seconds to wait before repeating the request. A Telegram→X scheduler should treat those numbers as a budget, queue outgoing Telegram messages per chat, and on a 429 wait exactly retry_after seconds before retrying, instead of hammering the API. This guide explains the limits, the error, and a queue design that keeps confirmations, receipts and digests flowing.
Which messages count against the limits?
When people talk about rate limits in a Telegram→X workflow, they usually mean X's API limits, which we cover in X API rate-limit budgets for Telegram schedulers. Telegram's limits are a separate budget, spent on the messages your bot sends back into Telegram:
- "Scheduled for 09:00" confirmations after a user sends a post
- Delivery receipts when a post goes live on X
- Failure notices and retry prompts
- Daily or weekly digests of what's queued
- Approval requests in a team group, if you use an approval gate
Each of those is a sendMessage (or similar) call, and each counts. A busy morning with many slots firing at once is when a bot is most likely to cross the line.
The three limits, in plain words
| Where | Limit from Telegram's FAQ | What it means for a scheduler |
|---|---|---|
| One chat | Avoid more than 1 message per second; short bursts may be allowed, then 429s | Space receipts for the same user at least a second apart |
| One group | No more than 20 messages per minute | Batch approval requests and receipts in team groups |
| All chats (bulk) | About 30 messages per second, unless paid broadcasts are enabled | Spread digests out rather than sending them all at 08:00 sharp |
The group limit is the one most schedulers hit first. Twenty messages a minute sounds like a lot, until ten posts fire at the top of the hour and each one sends a "posted" receipt plus a link preview check into the same team group.
What paid broadcasts change, and why most schedulers don't need them
Telegram lets a bot enable paid broadcasts in @BotFather to send up to 1,000 messages per second. Each message over the free 30 per second costs 0.1 Telegram Stars, paid from the bot's balance, and only successful messages are charged. To enable it, a bot needs at least 100,000 Stars on its balance and at least 100,000 monthly active users. Those thresholds put it out of reach for most small scheduling bots. Telegram's own suggestion for everyone else: spread broadcasts over longer intervals, for example 8 to 12 hours.
Reading a 429 correctly
When the Bot API rejects a request, the response has ok: false, an error_code and a human-readable description. For flood control, it can also carry a parameters object (the Bot API calls this ResponseParameters) with a retry_after field. The Bot API documentation defines it as "the number of seconds left to wait before the request can be repeated".
Three rules follow from that definition:
- Wait at least
retry_afterseconds. Retrying sooner just earns another 429. - Pause the right scope. If the 429 came from sending to one chat, pause that chat's queue. Don't stop the whole bot unless you see 429s across many chats.
- Don't treat it as a failure. A 429 means "not yet", not "never". The message should stay in the queue, not go to a dead-letter list.
That last point is where Telegram-side and X-side retries differ. Our failed-publish retry and dead-letter guide covers when an X publish should give up. A Telegram receipt that hits flood control should simply wait.
A queue design that stays under the limits
You don't need anything complicated. A small outbound queue with four parts handles it:
- One queue per chat. Every outgoing Telegram message goes into the queue for its chat ID, in order.
- A per-chat pacer. Each private chat sends at most one message per second; each group sends at most 20 per minute. A simple "next allowed send time" per chat is enough.
- A global pacer. Across all chats, stay well under about 30 messages per second.
- A 429 handler. On a 429, read
retry_after, set that chat's next allowed send time to now plusretry_after, and put the message back at the front of its queue.
Two refinements help a scheduler in particular:
- Coalesce receipts. If five posts from the same user go live within a minute, send one message listing all five instead of five messages.
- Jitter digests. Don't send every user's daily digest at exactly the same second; spread them over a window, as Telegram's FAQ suggests for broadcasts.
Combine this with the update_id dedupe from our webhook secret-token guide, so a retried webhook doesn't also produce a duplicate receipt.
What this looks like for an Auto X user
From the user's side, good rate-limit handling is invisible. You send a post to the bot in Telegram, get a confirmation, and later a receipt when it's live on X. If several posts fire at once, a well-behaved bot may group the receipts or deliver them a few seconds apart. That's the queue doing its job, not a delay in posting to X, which runs on its own schedule. If you want to set up scheduling from scratch, start with how to schedule X posts from Telegram.
How to test your pacing without getting flagged
Don't load-test against real users. Create a private test group with two or three accounts, point a staging copy of the bot at it, and queue more messages than the limits allow, for example 40 receipts for one group in a minute. Then check three things in your logs: that the pacer held the group to 20 per minute, that any 429 was followed by a wait of at least retry_after seconds, and that every queued message was eventually delivered in order. Repeat with one private chat and a burst of ten messages. If all three hold, the same code will hold in production. If the bot stays silent in that group, check privacy mode first; see why a Telegram bot isn't receiving group messages.
Common mistakes
- Fixed sleeps instead of
retry_after. A hard-coded one-second retry ignores what Telegram told you. - Retrying in parallel. Several workers retrying the same chat at once multiply the problem.
- Dropping messages on 429. Users then miss receipts and think a post failed.
- Top-of-the-hour pileups. Spread digests and batch receipts instead of sending everything at :00.
FAQ
Is the one-message-per-second limit strict?
Telegram's FAQ says it may allow short bursts above it, but you'll eventually get 429 errors. Design for one per second per chat and treat bursts as luck.
Does retry_after always appear on a 429?
The Bot API lists it as an optional field for flood control. If it's present, wait that many seconds; if it isn't, back off conservatively before retrying.
Do Telegram limits affect when my post goes live on X?
They shouldn't. Telegram limits apply to messages the bot sends in Telegram. Publishing to X is a separate API with its own limits.
Should a small bot enable paid broadcasts?
Usually it can't: Telegram requires at least 100,000 Stars on the balance and at least 100,000 monthly active users. Pacing and batching are the practical answer.
Sources
- Telegram Bots FAQ: "My bot is hitting limits, how do I avoid this?" (checked 2026-10-28)
- Telegram Bot API: making requests and ResponseParameters (retry_after) (checked 2026-10-28)