Back to blog

Telegram bot anti-spam: user quotas and overload behavior

Separate incoming user quotas from outgoing Telegram limits, then specify fair request budgets, rejection feedback, cancellation access, and concurrency checks.

Published October 16, 2026

Someone sends repeated queries, the bot accepts them all, and ordinary members stop getting timely responses. Slowing down outgoing messages alone may not help: too much work can already be running before any reply is sent.

This article concerns whether to accept a new user request, not broadcast delivery speed or turning repeated button clicks into one business operation. Prevent unnecessary work first, then complete accepted work according to explicit rules.

Protecting processing is different from limiting sends

The grammY user-rate-limiter guide distinguishes tracking users and stopping further processing from blocking Telegram's incoming network traffic. Its default identity key is from.id; keys and excess-request handling are configurable. It also warns against relying on in-memory tracking across a cluster.

The design implication is two separate controls: admission quotas protect business processing, while outgoing limits govern requests sent to Telegram. Neither replaces the other. The existing broadcast and retry guide addresses delivery; this article does not rebuild that queue.

Make four quota decisions

These are optional design choices, not Telegram's official allowances or product defaults:

  1. Who shares a budget? One user globally, a user within a group, or the whole group? Per-user-per-group budgets prevent one member directly consuming everyone else's personal allowance, but still need aggregate protection.
  2. Which actions count? Separate inexpensive help from heavier work. Unrelated conversation should not consume a query allowance.
  3. What does time mean? Fixed windows, rolling windows, and simultaneous-job limits are different promises. “Ten per minute” does not explain when capacity returns.
  4. What happens above the limit? Reject new work, offer a retry time, or use a bounded queue. An unlimited backlog should not be the implicit answer.

Derive identity from trusted update context, not a username supplied in message text. Define a separate policy for updates without an individual identity; neither put everyone into an accidental blank key nor grant unlimited access.

A small example with explicit boundaries

Suppose a reading-list bot accepts at most five queries per user per group in each aligned ten-second fixed window. These are illustrative values to tune through testing.

Use a consistent server-side clock. Requests above the allowance create no query job and make no changes to the reading list. Capacity returns at the next window. Adjacent windows can still permit a brief burst around their boundary, so do not advertise this as smooth traffic shaping. If no more than two queries may run simultaneously, specify a separate concurrency constraint.

Add group-wide or bot-wide capacity protection too. Many accounts staying below personal allowances can collectively overwhelm a service. Test per-person fairness separately from total system capacity rather than conflating them in one counter.

Rejection feedback must not become spam

We recommend at most one short notice per quota window, explaining that new work was not accepted and when retrying is possible. Do not send a long explanation for every rejected message or automatically broadcast recovery notices to everyone previously limited.

Cancellation and existing-job status can receive a separate, small reserved allowance so people can exit during overload. This is not an unlimited bypass. Administrator paths also need scoped safeguards; administrative status should not permit infinite expensive work.

Keep quota counters, job counts, and successful business outcomes separate. Rejecting a query must not create a success record. Decide in advance whether execution failures refund capacity, and do not repeatedly debit and refund without a consistency design.

Verify counter consistency in Serverless

“Store the counter in a database” is incomplete. Establish whether the available storage can consistently combine checking capacity with consuming it under concurrent requests, and define recovery after counters expire. A local simulation does not establish multi-instance correctness.

If the SDK cannot provide the required consistency, disclose the limited guarantee or disable the expensive entrance with a maintenance explanation. Do not promise a strict global quota. Adding an unsupported Redis client or arbitrary npm plugin is not an acceptable shortcut.

An editable requirement example

Add admission controls to a reading-list query feature: separate budgets for each user within a group, plus group-wide capacity and concurrency limits. First verify trusted identity, time, and consistent storage operations in the fixed SDK. Report any inability to guarantee concurrent accounting instead of promising strict limits. Only queries consume the query budget. Excess requests start no work and change no data, with at most one notice per window. Give cancellation and status their own small allowance. Use fictitious accounts to show accepted requests, rejected requests, and capacity recovery times.

This specifies behavior, not executable code. Tune allowance sizes, windows, and failure policies to actual usage.

Acceptance checks before release

  • Exceeding one person's allowance starts no new work; another person can still query normally.
  • The same person's activity in two groups follows the chosen scope without accidental sharing.
  • Window boundaries, clock interpretation, and recovery match the specification; concurrent requests do not exceed the promised acceptance count.
  • Multiple accounts trigger aggregate protection; disabling expensive work still provides a maintenance explanation.
  • Excess requests do not produce an equal flood of notices; cancellation remains available without an unlimited bypass.
  • Recheck accounting after deployment or execution-environment changes rather than assuming memory persists indefinitely.
  • Repeated updates do not repeat business side effects. This deduplication requirement remains separate from request quotas.

Use synthetic inputs and a dedicated test group, not a load test against a production community.

Applying this with BotFatherV2

BotFatherV2 creates and modifies Telegram bots through AI conversation. Clear quota scope, feedback rules, and acceptance inputs help you assess generated behavior. Publishing, importing existing Telegram Serverless bots, and rolling back code while retaining data do not automatically supply global counters or an abuse-prevention system.

Public development documentation checked on October 16, 2026 still restricts code to a fixed SDK without arbitrary npm packages or Node/Bun runtime APIs. The initial release does not add bot runtime features dependent on paid AI. The grammY documentation informs this design; it does not establish installed plugins, Redis support, or atomic quotas in BotFatherV2. This example does not require runtime model calls. BotFatherV2 is independent of Telegram's official BotFather and is not affiliated with Telegram.

Sources and date

  • grammY, Rate Limit Users (ratelimiter), particularly identity, excess-request behavior, and storage limits. No explicit publication date shown; accessed October 16, 2026.
  • Additional product-boundary check: BitBear Studio, Build with AI, accessed October 16, 2026.

Quota values, overload policies, and acceptance cases above are proposed designs, not Telegram or BotFatherV2 defaults.

Related articles

Continue with articles that share the same product tags.

Telegram join-request bots: approvals, invite links, and acceptance checks

Specify a verifiable Telegram admission workflow, distinguish requests from membership, audit shared-folder entry paths, and check BotFatherV2 implementation limits.

Telegram bot data missing after a group upgrade? Check chat IDs and migration

Diagnose apparent bot data loss when a basic group becomes a supergroup, then specify conflict handling, safe recovery, and migration acceptance checks.

Design a Telegram file-collection bot: identifiers, limits, and acceptance checks

Separate attachment registration, forwarding, and parsing, then specify file identifiers, business limits, access rules, and real Telegram acceptance checks.

Diagnose Telegram bot generation and publishing failures by stage

Separate queued tasks, generation checks, release failures, and real Telegram runtime errors with reproducible inputs and privacy-safe support evidence.

Design a multilingual Telegram bot: language selection, fallback, and interface copy

Separate client language, saved preferences, and message language, then define group policies, missing-copy fallback, stable buttons, and plural-form checks.

Design Telegram bot broadcasts: subscriptions, rate limits, and retries

Turn notification broadcasts into pausable, resumable jobs with consent, 429 handling, bounded retries, unsubscribe state, failure classes, and progress.