Skip to main content
Rate limits exist across Discord’s APIs to prevent spam, abuse, and service overload. Limits are applied to individual bots and users both on a per-route basis and globally. Individuals are determined using a request’s authentication — for example, a bot token for a bot.
Because rate limits depend on a variety of factors and are subject to change, rate limits should not be hard-coded into your app. Instead, parse response headers to prevent hitting the limit, and respond accordingly if you do hit it.

Per-route rate limits

Per-route rate limits exist for many individual endpoints, and may include the HTTP method (GET, POST, PUT, or DELETE). In some cases, per-route limits are shared across a set of similar endpoints, indicated in the X-RateLimit-Bucket header. Use this header as a unique identifier for a rate limit to group shared limits as you encounter them. During calculation, per-route rate limits often account for top-level resources within the path using an identifier — for example, guild_id when calling /guilds/{guild.id}/channels. Top-level resources are currently limited to:
  • Channels (channel_id)
  • Guilds (guild_id)
  • Webhooks (webhook_id or webhook_id + webhook_token)
This means that an endpoint with two different top-level resources may calculate limits independently. For example, if you exceeded a rate limit calling /channels/1234, you could still call /channels/9876 without a problem.

Global rate limits

Global rate limits apply to the total number of requests a bot or user makes, independent of any per-route limits. All bots can make up to 50 requests per second. If no authorization header is provided, the limit is applied to the IP address. Interaction endpoints are not bound to the bot’s global rate limit.
Routes for controlling emojis do not follow the normal rate limit conventions. These routes are limited on a per-guild basis to prevent abuse. The quota returned by the API may be inaccurate, and you may encounter 429s.

Header format

For most API requests, Discord returns optional HTTP response headers containing the rate limit information encountered during your request.
X-RateLimit-Limit: 5
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1470173023
X-RateLimit-Reset-After: 1
X-RateLimit-Bucket: abcd1234
HeaderDescription
X-RateLimit-LimitThe number of requests that can be made
X-RateLimit-RemainingThe number of remaining requests that can be made
X-RateLimit-ResetEpoch time (seconds since 00:00:00 UTC on January 1, 1970) at which the rate limit resets
X-RateLimit-Reset-AfterTotal time (in seconds) until the current rate limit bucket resets. Can have decimals for millisecond precision.
X-RateLimit-BucketA unique string denoting the rate limit being encountered (non-inclusive of top-level resources in the path)
X-RateLimit-GlobalReturned only on HTTP 429 responses if the rate limit encountered is the global rate limit (not per-route)
X-RateLimit-ScopeReturned only on HTTP 429 responses. Value can be user, global, or shared

Exceeding a rate limit

When a rate limit is exceeded, the API returns an HTTP 429 response code with a JSON body. Your application should rely on the Retry-After header or retry_after field to determine when to retry the request. Rate limit response structure
FieldTypeDescription
messagestringA message saying you are being rate limited
retry_afterfloatThe number of seconds to wait before submitting another request
globalbooleanA value indicating if you are being globally rate limited or not
code?integerAn error code for some limits

Example responses

< HTTP/1.1 429 TOO MANY REQUESTS
< Content-Type: application/json
< Retry-After: 65
< X-RateLimit-Limit: 10
< X-RateLimit-Remaining: 0
< X-RateLimit-Reset: 1470173023.123
< X-RateLimit-Reset-After: 64.57
< X-RateLimit-Bucket: abcd1234
< X-RateLimit-Scope: user
{
  "message": "You are being rate limited.",
  "retry_after": 64.57,
  "global": false
}

Global rate limit bans

If your bot gets big enough, based on its functionality, it may be impossible to stay below 50 requests per second during normal operations. Global rate limit issues generally show up as repeatedly getting banned from the Discord API when your bot starts.
If your bot gets temporarily Cloudflare banned every once in a while, it is most likely not a global rate limit issue. You probably had a spike of errors that was not properly handled and hit the error threshold.
If you are experiencing repeated Cloudflare bans within normal operations of your bot, contact Discord support to see if you qualify for increased global rate limits at https://dis.gd/rate-limit.

Invalid request limit

IP addresses that make too many invalid HTTP requests are automatically and temporarily restricted from accessing the Discord API. Currently, this limit is 10,000 invalid requests per 10 minutes. An invalid request is one that results in 401, 403, or 429 statuses. All applications should make reasonable attempts to avoid invalid requests:
  • 401 responses are avoided by providing a valid token in the authorization header when required and stopping further requests after a token becomes invalid.
  • 403 responses are avoided by inspecting role or channel permissions before making requests restricted by such permissions.
  • 429 responses are avoided by inspecting the rate limit headers and not making requests on exhausted buckets until after they reset.
429 errors returned with X-RateLimit-Scope: shared are not counted against the invalid request limit.
Large applications that can potentially make 10,000 requests per 10 minutes (a sustained 16–17 requests per second) should consider logging and tracking the rate of invalid requests to avoid this hard limit. In addition, account for other invalid statuses. If a webhook returns a 404 status, do not attempt to use it again — repeated attempts will result in a temporary restriction.