Skip to content

Discord: Add delay between multi-chunk messages to avoid rate limits #349

@cash-echo-bot

Description

@cash-echo-bot

Problem

When sending long messages that exceed Discord's 2000 character limit, sendDiscordText() splits them into chunks and sends them back-to-back in a tight loop:

for (const chunk of chunks) {
  last = await rest.post(Routes.channelMessages(channelId), {...});
  isFirst = false;
}

While @buape/carbon has built-in rate limit handling with request queuing, it only auto-retries global rate limits. Per-route limits (like the ~5 messages/5 seconds per channel) throw RateLimitError and bubble up.

This causes intermittent failures when sending messages that split into 3+ chunks, as rapid-fire sends can exceed the per-channel rate limit.

Solution

Add a small delay (e.g., 1 second) between chunk sends:

const DISCORD_CHUNK_DELAY_MS = 1000;

for (const chunk of chunks) {
  if (!isFirst) {
    await new Promise((resolve) => setTimeout(resolve, DISCORD_CHUNK_DELAY_MS));
  }
  last = await rest.post(Routes.channelMessages(channelId), {...});
  isFirst = false;
}

This keeps us well under the per-channel rate limit while only adding latency for multi-chunk messages.

Context

  • Discord global limit: 50 req/sec
  • Per-channel message limit: ~5 messages per 5 seconds
  • @buape/carbon v0.13.0 handles global limits automatically but throws on per-route limits
  • Fix adds ~1s delay between chunks (after the first), so a 3-chunk message takes ~2s extra

Already Implemented

I've implemented this fix locally and can submit a PR if desired. Tests pass and the delay is only incurred for multi-chunk sends.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions