Discord rate limits are the guardrails that keep the API usable for everyone. Hit them too hard and Discord will slow your bot down, or even ban it. Understanding them prevents both.
How Rate Limits Work
Every Discord API endpoint has a rate limit - a maximum number of requests per time window. When you exceed the limit:
- Discord returns HTTP 429 (Too Many Requests)
- The response includes
Retry-Afterheader with wait time - Your bot must wait before making more requests
Rate Limit Types
Per-Route Limits
Each API endpoint has its own limit:
- Send message: 5 per 5 seconds per channel
- Edit message: 5 per 5 seconds per channel
- Delete message: 5 per 1 second per channel (special rate)
- Bulk delete: 1 per 1 second per channel
- Reactions: 1 per 0.25 seconds per channel
Global Limits
50 requests per second across all endpoints. Exceeding this affects all bot operations.
Per-Resource Limits
Some limits are per-guild or per-channel, not per-bot. Multiple bots in the same guild share these limits.
How discord.js Handles It
discord.js has built-in rate limit handling:
const client = new Client({
rest: {
timeout: 15000,
retries: 3
}
});
It automatically:
- Queues requests when approaching limits
- Waits when receiving 429 responses
- Retries failed requests
Rate Limit Events
client.rest.on('rateLimited', (info) => {
console.warn(`Rate limited: ${info.route} - Retry after ${info.retryAfter}ms`);
});
Common Mistakes
Spamming Messages
// BAD: Sends 100 messages instantly, hits rate limit
for (const user of users) {
await channel.send(`Hello ${user}!`);
}
// GOOD: Batch into one message
const userList = users.map(u => u.toString()).join(', ');
await channel.send(`Hello ${userList}!`);
Mass Operations
// BAD: Banning 50 users simultaneously
users.forEach(async user => {
await guild.members.ban(user);
});
// GOOD: Sequential with delay
for (const user of users) {
await guild.members.ban(user);
await new Promise(resolve => setTimeout(resolve, 1000)); // 1s between bans
}
Reaction Spam
// BAD: Adding 10 reactions instantly
emojis.forEach(async emoji => {
await message.react(emoji);
});
// GOOD: Sequential with delay for reaction rate limit
for (const emoji of emojis) {
await message.react(emoji);
await new Promise(resolve => setTimeout(resolve, 300));
}
Prevention Strategies
Request Caching
Don't request data you already have:
// BAD: Fetching channel every time
async function sendMessage(channelId, content) {
const channel = await client.channels.fetch(channelId);
await channel.send(content);
}
// GOOD: Use cache first
async function sendMessage(channelId, content) {
const channel = client.channels.cache.get(channelId)
|| await client.channels.fetch(channelId);
await channel.send(content);
}
Bulk Operations
Use bulk endpoints when available:
// Instead of deleting messages one by one:
await channel.bulkDelete(50); // Deletes up to 100 messages in one request
Queue System
For features that could generate many API calls:
const actionQueue = [];
let processing = false;
function queueAction(action) {
actionQueue.push(action);
if (!processing) processQueue();
}
async function processQueue() {
processing = true;
while (actionQueue.length > 0) {
const action = actionQueue.shift();
try {
await action();
} catch (error) {
if (error.httpStatus === 429) {
actionQueue.unshift(action); // Re-queue
await new Promise(resolve => setTimeout(resolve, error.retryAfter));
}
}
await new Promise(resolve => setTimeout(resolve, 100)); // Minimum delay between actions
}
processing = false;
}
Monitoring
Track your rate limit hits:
let rateLimitCount = 0;
client.rest.on('rateLimited', () => {
rateLimitCount++;
});
setInterval(() => {
if (rateLimitCount > 0) {
console.log(`Rate limits hit in last hour: ${rateLimitCount}`);
rateLimitCount = 0;
}
}, 3600000);
If rate limit hits increase over time, your bot needs optimization.
What Happens if You Ignore Limits
- Cloudflare ban: Persistent 429 abuse results in your bot's IP being temporarily banned by Discord's CDN
- Token revocation: Extreme abuse leads to your bot token being revoked
- API ban: Your application can be banned from the API entirely
Take rate limits seriously. They protect both Discord and your bot's reliability. On Space-Node hosting, your bot has a stable IP and connection - consistent rate limit handling is easier when your network is reliable.
