Skip to content

Rate Limits

ai& enforces rate limits per organization to keep the platform healthy under shared load. Limits depend on your tier and apply to inference endpoints; management APIs have their own (looser) limits.

TierDescription
Tier 0Evaluation tier. Lower per-minute caps. Suitable for development and small projects. New orgs start here.
Tier 1Production tier. Higher caps and access to higher-throughput models. Orgs are promoted on their first successful payment.

Each request is checked against six buckets — four per-model and two per-org global:

  • Per-model RPM — requests per minute against one specific model.
  • Per-model Input TPM — input tokens per minute (estimated up-front from the request body).
  • Per-model Output TPM — output tokens per minute (charged after the response completes).
  • Per-model Concurrency — max in-flight requests against one model.
  • Global RPM — requests per minute across all models you call.
  • Global Concurrency — max in-flight requests across all models.

Whichever bucket fills first triggers throttling.

Every authenticated inference request that reaches model admission reports each bucket that applies to you — including 200 responses, streams, and 429 responses from one of these six buckets. The first two rows use OpenAI’s header names and formats unchanged, so tools that already read them keep working; the rest extend the same pattern.

BucketHeaders
Per-model RPMx-ratelimit-limit-requests, x-ratelimit-remaining-requests, x-ratelimit-reset-requests
Per-model Input TPMx-ratelimit-limit-tokens, x-ratelimit-remaining-tokens, x-ratelimit-reset-tokens
Per-model Output TPMx-ratelimit-limit-output-tokens, x-ratelimit-remaining-output-tokens, x-ratelimit-reset-output-tokens
Per-model Concurrencyx-ratelimit-limit-concurrency, x-ratelimit-remaining-concurrency
Global RPMx-ratelimit-limit-global-requests, x-ratelimit-remaining-global-requests, x-ratelimit-reset-global-requests
Global Concurrencyx-ratelimit-limit-global-concurrency, x-ratelimit-remaining-global-concurrency
  • limit-* is the bucket’s cap and remaining-* what is left in it right now. remaining-tokens counts input only — output tokens are charged after the response completes.
  • reset-* is the time until that bucket is full again, as a duration like 45s or 6m0s. Concurrency buckets have no reset: they free up as in-flight requests finish.
  • A bucket your tier has no cap on (an Input/Output TPM or global cap of 0) is omitted. A limit-requests or limit-concurrency of 0 means the opposite — that model is closed to your tier, and no wait will open it.

On a 429 Too Many Requests from one of these six model buckets, two more headers are added:

HeaderMeaning
X-RateLimit-PolicyWhich bucket denied the request: rpm, global_rpm, input_tpm, output_tpm, concurrency, or global_concurrency.
Retry-AfterSeconds until this request fits — shorter than reset-*, which waits for the whole bucket. Omitted for concurrency and global_concurrency rejects — finish or cancel in-flight requests instead.

The earlier X-RateLimit-Limit and X-RateLimit-Remaining headers remain as deprecated compatibility aliases. New integrations should use the explicit headers above. Authentication throttles happen before model admission and carry Retry-After without X-RateLimit-Policy or bucket headers. Public catalog endpoints such as GET /v1/models are not metered this way and carry none of these headers.

See Response Headers for non-rate-limit headers.

When throttled, ai& returns 429 Too Many Requests. The two kinds of bucket clear differently, so read X-RateLimit-Policy and handle the reject by its type — the same “back off and retry” is wrong for a concurrency reject.

Time-based rejects — rpm, global_rpm, input_tpm, output_tpm. These refill as the window advances. Retry-After gives the minimum safe delay: wait at least that long, then retry with exponential backoff and jitter.

Concurrency rejects — concurrency, global_concurrency. These clear only when in-flight requests finish or are cancelled, not with time, so no Retry-After is sent. Let existing requests drain, or lower your concurrency, before sending more.