Telegraft

Bot API reference

Twenty messages a minute, into any one group

A bot may send approximately 20 messages per minute into a single group or supergroup. This is a separate and far tighter budget than the bot-wide send rate, it is measured per chat, and it is the limit a moderation or community bot meets long before it meets any other.

Per-group message limit: the exact figures

Per-group send rate
~20 messages/minute into a single group
Per-group rate
~20 messages/minute
Effective cadence
One message every 3 seconds, sustained
Interaction with the global limit
Both apply; either can bind first
Editing
The standard way to report changing state without spending sends

As of 2025-10-01, Telegram Bot API 13.4

What it means in practice

The number reads as generous and behaves as the opposite, because it is a rate rather than an allowance. Twenty per minute is one message every three seconds, sustained. It is not twenty in the first second followed by a pause; a bot that replies to every message in an active group during a launch will exhaust the budget inside a few seconds and spend the rest of the minute throttled, at exactly the moment its answers were worth most.

This changes how a group-facing bot should be designed, and the change is architectural rather than a tuning parameter. A bot that posts one confirmation per user action does not scale past a quiet room. The patterns that survive are aggregation and editing: collect several events and post one summary, or post once and edit that message as the state changes. Editing does not consume the send budget in the same way, which makes a single edited status message the standard answer for anything that updates frequently.

Moving conversation out of the group is the other reliable move, and it is usually better product design as well. A moderation bot that explains a removal in the group is spending its scarcest resource on a message most members do not want; the same explanation sent to the affected user privately costs nothing from the group budget and is more likely to be read. Public posts are reserved for what genuinely belongs in public.

The limits compose rather than replace each other. A bot serving forty groups is bounded per group at twenty a minute and bounded overall by the roughly thirty per second bot-wide ceiling, and it can exhaust either first. A moderation bot in one very busy group hits the per-group limit; the same bot across four hundred groups hits the global one. Which of the two binds is a question about the deployment, not about the code, and it is worth answering before the design is fixed rather than after.

Handling it in code

// One status message, edited, instead of one message per event.
const statusByChat = new Map<number, number>()

async function reportProgress(chatId: number, done: number, total: number): Promise<void> {
  const text = `Processing ${done} of ${total}`
  const existing = statusByChat.get(chatId)

  if (existing === undefined) {
    const sent = await bot.api.sendMessage(chatId, text)
    statusByChat.set(chatId, sent.message_id)
    return
  }

  // Editing to identical content throws, so skip the no-op rather than catching it later.
  await bot.api.editMessageText(chatId, existing, text)
}
The pattern that keeps a progress report inside the per-group budget: post once, edit thereafter. Note the no-op guard — re-editing a message to text it already has is an error, not a silent success.

Questions this raises

Does replying to a message count against the group limit?

Yes. A reply is a message in the group like any other, and the fact that it is threaded to a specific post does not exempt it. This is why a bot that answers every mention in a busy community throttles itself during exactly the events it was bought for.

Do channel posts share this limit?

A channel is a different chat type and behaves differently in practice, which is much of the reason broadcast-style products use channels rather than groups. One channel post reaches every subscriber as a single message, whereas reaching the same people individually costs one send each against the bot-wide budget.

Is deleting a message cheaper than not sending it?

No, and this is worth stating because moderation bots often assume otherwise. A delete is an API call like any other. A bot that posts a warning and removes it seconds later has spent two calls to achieve what a private message to the offender would have achieved with one, without consuming the group budget at all.

How do I know which limit I am actually hitting?

The 429 response names a retry_after but not which budget was exhausted, so the diagnosis comes from context: throttling concentrated in one busy chat is the per-group limit, throttling spread evenly across many chats during a broadcast is the global one. Logging the chat id alongside every 429 makes the difference obvious in a minute rather than an afternoon.

Related limits