Rate LimitsAPIOptimization4 min read

Handle Discord API rate limits

Understanding the bucket system, handling 429 responses, implementing queues and best practices.


What are rate limits?

Discord limits the number of requests you can make to its API to prevent abuse. If you exceed the limit, you receive a 429 (Too Many Requests) error and your bot is temporarily blocked.

How the bucket system works

Each endpoint has its own rate limit bucket:

terminal
Response headers:
X-RateLimit-Limit: 5          # Allowed requests
X-RateLimit-Remaining: 3      # Remaining requests
X-RateLimit-Reset: 1672531200 # Reset timestamp
X-RateLimit-Bucket: abc123    # Bucket ID

Important global limits:

  • 50 requests/second per bot (global)
  • 5 messages/5 seconds per channel
  • Slash commands: 200 creates/day (global), unlimited per guild

Handle 429 automatically

discord.js handles rate limits internally, but you can monitor them:

javascript
const { Client } = require('discord.js');

const client = new Client({ /* intents */ });

// Rate limit event
client.rest.on('rateLimited', (info) => {
  logger.warn('Rate limited', {
    route: info.route,
    timeout: info.timeToReset,
    limit: info.limit,
    method: info.method
  });
});

// Configure retries
const { REST } = require('discord.js');
const rest = new REST({
  retries: 3,
  timeout: 15000
}).setToken(process.env.DISCORD_TOKEN);

Implement a message queue

For bots that send many messages:

javascript
class MessageQueue {
  constructor() {
    this.queue = new Map(); // channelId -> messages[]
    this.processing = new Set();
  }

  async send(channel, content) {
    const channelId = channel.id;
    if (!this.queue.has(channelId)) {
      this.queue.set(channelId, []);
    }
    this.queue.get(channelId).push(content);

    if (!this.processing.has(channelId)) {
      this.processing.add(channelId);
      await this.processQueue(channel);
    }
  }

  async processQueue(channel) {
    const messages = this.queue.get(channel.id);
    while (messages.length > 0) {
      const content = messages.shift();
      await channel.send(content);
      await new Promise(r => setTimeout(r, 1100)); // 1 msg/sec safe
    }
    this.processing.delete(channel.id);
  }
}

Best practices

javascript
// Bad: send many messages in a row
for (const user of users) {
  await channel.send(`Welcome ${user}`);
}

// Good: combine into a single message or embed
const welcomeList = users.map(u => `- ${u}`).join('\n');
await channel.send(`**Welcome:**\n${welcomeList}`);

// Good: use bulk operations
await channel.bulkDelete(messages, true); // Instead of deleting one by one

Recommendations

  • Let discord.js handle rate limits automatically
  • Monitor the rateLimited event to detect issues
  • Combine messages when possible
  • Use queues for bulk operations
  • Cache data instead of making repeated API requests

Was this guide helpful?