Discord API rate limits (429) explained for bot developers
What Discord 429 rate limits are, how discord.js and discord.py handle them for you, and which bot patterns trigger them so you can avoid them.
Updated · 2 min read
A 429 response means your bot sent too many requests to the Discord API in a short time and must wait before trying again. discord.js and discord.py queue and retry rate-limited requests automatically, so a few 429s are normal. Constant rate limiting means your bot is doing something too often.
How rate limits work
Discord limits requests in a few ways:
| Limit | What it covers |
|---|---|
| Per-route limits | Each endpoint (for example, sending messages to a channel) has its own bucket. |
| Global limit | A cap on total requests per second across your whole bot. |
| Invalid request limit | Too many failed requests (401, 403, 429) in a short window gets your IP temporarily blocked. |
| Gateway limits | Sending too many events over the gateway connection, and a daily limit on logins. |
Discord tells the library how long to wait using response headers, and the library waits before retrying. You don't need to parse these yourself.
Seeing rate limits in your logs
discord.js emits an event you can log:
client.rest.on('rateLimited', (info) => {
console.warn(`Rate limited on ${info.route}, retry in ${info.timeToReset} ms`);
});
discord.py logs a warning through the discord.http logger when it's rate limited, so it shows up in your console with normal logging enabled.
Common causes and fixes
Bulk actions in a loop
Sending a DM to every member, adding a role to everyone, or deleting messages one by one hits limits quickly. Instead:
- Use bulk endpoints where they exist (
channel.bulkDelete()in discord.js,channel.purge()in discord.py). - Spread large jobs out over time.
- Avoid mass DMs; they also risk your bot being flagged.
Editing messages or channels too often
A live-updating "status" message edited every second will be rate limited. Edit every 30 to 60 seconds instead. Channel name and topic changes have especially tight limits (a couple of changes per 10 minutes per channel), so don't use channel names as live counters.
Retrying failed requests yourself
Wrapping API calls in your own fast retry loop adds to the problem. Let the library handle 429s and only retry on your side with a delay.
Repeated permission errors
Requests that fail with Missing Permissions or Missing Access still count toward the invalid request limit. Check permissions before acting, and stop retrying actions that can't succeed.
Crash loops
Each restart logs in again. Discord limits logins per day, and if a crash loop uses them all up, Discord resets your token. See bot keeps going offline.
Syncing slash commands on every start
Registering commands is rate limited. Sync only when commands change, or at least not on every reconnect.
Temporary IP blocks
If your bot keeps failing requests, Cloudflare may block requests from your IP for a while, and you'll see an HTML error page (often mentioning error 1015) instead of a normal API error. Stop the bot, fix whatever is causing failed requests, and wait before starting again. Restarting repeatedly makes it last longer.
Further reading
The discord.js guide and the discord.py docs cover library-specific options.