NexaDocs
DocsPlatformRate Limits

Rate Limits

Rate limiting is how a service protects itself from being overwhelmed — by one runaway client, by a bug in someone's code, or by a flood of simultaneous requests. This page explains the general concepts behind rate limiting the way most modern APIs (including Discord's) implement them, and then covers the concrete, current rate-limit system in Nexa Assistant, which is the one real, user-facing limit in the Nexa product line today.

Scope of this page

Nexa doesn't have a public developer API yet (see Nexa API), so there's no bucket-per-endpoint system to document today. The concepts below are the general model used across the industry — useful background if you've ever hit a 429 anywhere — and the real, current system for Nexa Assistant is described in its own section further down.

Why rate limits exist

Without limits, a single client — a script with a bug, a tight retry loop, or just a very enthusiastic integration — could send far more requests than a service can handle, degrading things for everyone else. Rate limits exist to:

  • Keep the service responsive under load for all users
  • Prevent a single bad actor or bug from causing an outage
  • Give a service predictable, plannable capacity

Core concepts

Buckets

Instead of one global counter, most rate-limited APIs group related requests into buckets — a bucket is a specific pool of "requests you're allowed to make in a time window" for a specific scope. A bucket might be scoped to:

  • A single endpoint (e.g., "send a message in this channel")
  • A group of related endpoints that share a limit
  • A specific resource, like a specific channel or user ID

The reason buckets exist rather than one single counter: an API needs many different operations to be available at once without one heavy user of Feature A starving out everyone using Feature B.

Route-specific limits

A route-specific limit applies to one particular action or endpoint — for example, "you can only edit a specific message 5 times per 5 seconds." Hitting this limit only affects that specific action; other requests to different endpoints are unaffected.

Global limits

A global limit is a ceiling on the total number of requests a client can make across all endpoints combined, regardless of which specific bucket each request belongs to. This exists as a backstop — even if a client is carefully respecting every route-specific bucket, a global limit prevents it from making an unreasonable number of total requests per second.

Retry-After

When a request is rejected for being over a limit, the response almost always includes a Retry-After value — the number of seconds (or milliseconds) the client should wait before trying again. A well-behaved client reads this value and waits accordingly rather than guessing.

json
{
  "message": "You are being rate limited.",
  "retry_after": 1.372,
  "global": false
}

In this example, global: false tells the client this is a route-specific limit, not a global one — so requests to other endpoints can continue immediately; only this specific action needs to wait.

How Discord's system works, specifically

Discord's API is a well-known real-world example of this bucket model, and it's worth understanding because the same shape shows up across the industry:

  • Each route (or group of routes sharing a limit) has its own bucket, identified by a hash Discord returns in response headers
  • Response headers tell you your current standing in that bucket:
    • X-RateLimit-Limit — total requests allowed in the current window
    • X-RateLimit-Remaining — requests left in the current window
    • X-RateLimit-Reset-After — seconds until the window resets
    • X-RateLimit-Bucket — an identifier for which bucket this response belongs to, so a client can track buckets even when the exact route path varies (e.g., different channel IDs sharing one bucket)
  • On top of all route buckets, a global limit caps total requests per second regardless of bucket
  • Getting rate limited repeatedly, or ignoring Retry-After, can escalate to temporary blocks

The takeaway that generalizes beyond Discord specifically: track limits per-bucket using response headers, respect Retry-After exactly, and treat the global limit as a hard ceiling that applies no matter what.

Best practices

  • Read the headers, don't guess. If a service returns rate-limit headers, use them to pace your requests instead of hardcoding a fixed delay.
  • Respect Retry-After exactly. Waiting slightly less than instructed risks getting rate limited again immediately; waiting a bit longer is safe.
  • Use exponential backoff for anything without explicit headers. If a service doesn't tell you exactly how long to wait, back off exponentially (e.g., 1s, 2s, 4s, 8s) rather than retrying immediately in a tight loop.
  • Cache aggressively. The cheapest request is the one you don't make — if data doesn't change often, don't re-fetch it on every action.
  • Batch where possible. If a service supports bulk operations, prefer them over many individual requests.

Common mistakes

  • Retrying immediately in a loop. This is the single most common cause of a temporary IP or account-level block — it looks identical to abuse from the service's perspective, even if unintentional.
  • Ignoring the global limit. Carefully respecting every route-specific bucket doesn't help if you're still blowing through the global ceiling.
  • Not distinguishing global: true responses. A globally rate-limited response means everything needs to pause, not just the one endpoint that returned it.
  • Hardcoding a fixed delay instead of reading Retry-After. Limits can vary by load and by account state; a hardcoded guess will eventually be wrong in both directions.

Nexa Assistant's current limit system

Nexa Assistant enforces a simpler, account-level daily limit rather than a per-endpoint bucket system, since there's no public API surface to bucket against yet.

TierDaily messages
Free30
Pro Coming Soon500
  • The count resets 24 hours after your first message of the day
  • Effort level affects cost: Low and Balanced cost 1 message each, High effort costs 2 messages
  • Once your daily allowance is used up, further requests are blocked until the reset

See Accounts & Limits for the full breakdown, and Errors for what you'll see in the interface when you hit this limit.

FAQ

Is Nexa Assistant's limit a "bucket" system like Discord's? No — it's a single daily counter per account, not multiple per-endpoint buckets. The concepts above are useful background, but Nexa Assistant's actual implementation today is much simpler.

Will there be per-endpoint rate limits once a public API ships? Undetermined — this page will be updated with the real system once the Nexa API is available.

What should I do if I'm building something and get rate limited? For Nexa Assistant, wait for your daily reset or reduce how often you use High effort. There's currently no way to request a higher limit outside of the (not-yet-available) Pro tier.