Telegram does not enforce one broadcast limit. It enforces mechanical rate caps you can engineer around, and behavioural limits you can only earn your way past — this guide covers both.
Telegram's bot platform is built to protect the person receiving the message, not the person sending it. That design decision explains every limit you will run into. There are three separate families of restriction, and confusing them is the most common reason a send goes wrong.
Engineering fixes the first family. Nothing but editorial discipline fixes the third. Most teams that get burned spend all their effort on retry logic and none on cadence.
Telegram documents a broad ceiling around 30 messages per second spread across different chats, and roughly one message per second to the same chat. Groups are tighter still. These are soft ceilings: the platform can quietly narrow them for a bot that produces reports or sends in aggressive bursts, so build for a pace comfortably under the published number rather than pinned to it.
When you exceed a cap, the API answers with 429 Too Many Requests and a retry_after value in seconds. The only correct response is to stop that worker for exactly that long and resume in order. Retrying straight away, or fanning the same queue out across more workers to dodge the wait, extends the throttle and can escalate it into something longer-lived.
A sane sending queue has four properties. One ordered queue per bot, so two operators cannot start overlapping sends. A token bucket that paces below the ceiling. A hard split between transient failures (network errors, 5xx, 429) which are retried a bounded number of times, and terminal failures (the user blocked the bot, the chat is gone) which are never retried. And a stored per-recipient result, so a resumed or repeated send does not deliver twice.
That classification step matters more than the pacing. A queue that keeps retrying 403 responses will spend hours hammering people who already left, while the subscribers who are still with you wait at the back of the line. mySkua runs broadcasts server-side with bounded retries, and drops subscribers who have blocked the bot instead of retrying them forever — see how broadcasts work.
A block is loud. The user taps Block, and every subsequent send to that chat returns a 403 error saying the bot was blocked. You can count blocks, chart them, and act on them. They are also honest: the person has told you to stop, and the only correct handling is to mark them and stop.
A mute is silent, and far more dangerous. The chat stays in the user's list, your message is still accepted, and it still counts as delivered — it simply never makes a sound. Nothing in the API tells you it happened. A heavily muted list looks perfect on a delivery report and produces almost nothing.
This is why delivery rate on its own is a lying metric for a broadcast message. The signal that catches mutes is engagement measured against delivery: inline-button clicks and campaign activations. When deliveries stay flat while clicks fall away over consecutive sends, you are being muted, and that is the leading indicator of subscriber churn — the blocks arrive weeks later.
There is no universal safe cadence, because tolerance is set at opt-in. Someone who joined for a specific promo code expects a promo code, not a daily newsletter. Three rules travel well across funnels:
Repetition is the quiet killer. Re-sending an offer to people who already claimed it reads as carelessness. Campaigns in mySkua activate once per subscriber, so a claimed offer stops following that person around.
Every irrelevant message spends attention you cannot get back, and the whole-list blast is the most expensive way to spend it. Segmenting is not only a relevance tactic — it is also a limits tactic, because a send to four thousand targeted subscribers finishes well inside the rate ceiling while a send to forty thousand does not.
The dimensions worth using are the ones you already collect during onboarding: language chosen at /start, the category the subscriber picked for themselves, the source recorded from the deep-link payload, and tags applied along the way. A subscriber who selected Sport should not receive a casino offer. A subscriber who arrived through an Instagram deep link should get copy that matches the creative they clicked, because they remember it. Auto-messages and broadcasts can both be aimed at those attributes rather than at everyone.
Segmented sends also make results readable. When one message goes to one audience, a drop in activations tells you something specific. When one message goes to the whole list, it tells you nothing you can act on.
A single 09:00 broadcast is 09:00 in exactly one place. If your list spans Lisbon, Budapest and Manila, one send time means somebody is being woken up — and a notification at 03:00 buys you a mute at best. Language is a reasonable proxy for region when you have nothing better, and it is a dimension you already store.
Two practical habits: schedule recurring broadcasts per timezone rather than in server time, so daily and weekly sends land in the reader's morning and stay put through daylight-saving shifts; and avoid the exact top of the hour, where every automated marketing system on the planet is already queued. Staggering regional sends across the hour also spreads your own API traffic, which keeps you further from the rate ceiling on a large list.
Check these immediately after each send, not once a month, because the useful comparison is send-over-send:
Recovery starts with silence. Nothing improves while the volume that caused the problem continues, so stop broadcasting for a defined pause — long enough that your next message is a small surprise rather than more of the same. Then restart deliberately:
Roughly 30 per second across different chats, and about one per second to the same chat, as a documented soft ceiling. Pace under it rather than at it, since the platform can narrow the limit for bots that attract reports.
You receive 429 Too Many Requests with a retry_after value. Wait exactly that long, then resume in order. Do not retry immediately and do not add workers to route around the wait.
No. Mutes are invisible and the message still counts as delivered. Infer them from engagement falling while delivery stays flat.
As often as you can name a concrete payoff for the recipient. Automation timed to the subscriber's own lifecycle sustains a far higher frequency than repeated blasts to the whole list.
Most of the work above is infrastructure: paced sending with bounded retries, terminal errors separated from transient ones, blocked subscribers dropped automatically, recurring sends scheduled per timezone, drips targeted by language, category, source or tag, and delivery plus activation data sitting next to retention cohorts so you can see damage while it is still small.
That is what mySkua does for Telegram lead-generation bots, with each bot keeping its own subscribers, content and team. The platform is currently in invite-only private beta — if you run Telegram funnels and want to try it, join the waitlist and request access, and we will get in touch.
Want this on your own bots?
mySkua is in a closed beta and accounts are opened in small batches. Tell us what you run and we will come back to you.
Request access