Why limits exist
Platforms share infrastructure between millions of bots and users. Limits protect that infrastructure and protect users from spam. For a bot developer they also define the maximum speed of anything you build: a broadcast to 10,000 users at 30 messages per second takes over five minutes no matter how fast your server is.
How limits are measured
Most APIs implement one of three algorithms. You can watch them side by side in the rate limiter playground.
- Fixed window: N requests per window (for example per minute). Simple, but allows up to twice the limit around the window boundary.
- Sliding window: counts requests in the last N seconds at any moment. Smoother and stricter.
- Token bucket: a bucket refills at a steady rate; each request takes a token; short bursts are allowed up to the bucket size.
Limits also have a scope: per chat, per channel, per route, per bot or per app. A bot can be well under its global limit and still be throttled in a single busy chat.
The limits that matter most
| Platform | Documented limit | Scope |
|---|---|---|
| Telegram | About 1 message per second | Per chat |
| Telegram | 20 messages per minute | Per group |
| Telegram | About 30 messages per second | Overall broadcasting |
| Discord | 50 requests per second | Global, per bot |
| Discord | Varies, reported in headers | Per route (bucket) |
| Slack | Tiers from Tier 1 to Tier 4; chat.postMessage about 1 per second |
Per method, per workspace; per channel |
| WhatsApp Cloud API | 80 messages per second by default | Per business phone number |
Exact figures, sources and last-checked dates are in our rate limits table. The comparison tool estimates how long a send of N messages takes on each platform.
Reading a 429
HTTP 429 Too Many Requests means "slow down". The response usually tells you for how long:
- The standard
Retry-Afterheader, in seconds. - Telegram returns
parameters.retry_afterin the JSON body. - Discord returns
retry_afterin the body andX-RateLimit-*headers that describe the bucket, includingX-RateLimit-RemainingandX-RateLimit-Reset-After, so you can slow down before hitting the limit.
Always wait at least the time the server asks for. Retrying immediately extends the penalty, and repeated invalid requests can get a bot temporarily blocked: Discord documents a limit on invalid requests (401, 403 and 429 responses) per IP address.
Backoff with jitter
For errors without a server-provided delay (timeouts, 502, 503), retry with exponential backoff and jitter: wait a random time between zero and a cap that doubles after each failure. The jitter prevents all your workers from retrying at the same instant. Limit the number of attempts and only retry idempotent operations, or use an idempotency key. The backoff calculator generates the schedule and code.
Throttle before you hit the limit
The best 429 is the one you never get:
- Put sends in a queue instead of calling the API from every handler.
- Throttle per scope: one token bucket per chat plus one global bucket.
- Spread broadcasts over time and send them at a rate below the documented limit, leaving headroom for interactive replies.
- Prioritize: replies to users first, bulk messages after.
- Track 429s as a metric. A rising count is an early warning.
Common mistakes
- Treating limits as global when they are per chat (or the opposite).
- Running several instances that each think they own the whole limit. Use a shared limiter (Redis, a Durable Object) or one sender process.
- Retrying 4xx errors other than 429: a bad request will fail again.
- Hard-coding limits without a source. Platforms change them; keep the number in configuration.
Sources
- Telegram Bots FAQ: core.telegram.org/bots/faq
- Discord rate limits: discord.com/developers/docs/topics/rate-limits
- Slack rate limits: api.slack.com/apis/rate-limits
- WhatsApp Cloud API throughput: developers.facebook.com/docs/whatsapp/cloud-api/overview
- RFC 6585, status code 429: rfc-editor.org/rfc/rfc6585