> ## Documentation Index
> Fetch the complete documentation index at: /docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Rate limits and quotas

> Understand how the AI Gateway enforces plan-based rate limits, budget limits, and provider quotas, and how to read 429 responses and headers.

**Toqan Router** enforces limits at three layers. Every request to the **AI Gateway** passes a plan-based platform rate limit, any **Budget** limits that match the request, and finally the upstream provider's own quotas. Knowing which layer rejected a request is the first step to fixing it.

| Layer | Enforced by | Configurable | Applies to |
| - | - | - | - |
| Platform rate limits | **Toqan Router**, per workspace plan | Enterprise plans by arrangement | Every request to the gateway |
| Budget limits | **Toqan Router**, from configured budgets | Yes, under **Settings > Organization > [Budgets](/docs/ai-gateway/budgets.md)** | Requests matching the budget scope |
| Provider rate limits | The upstream provider account | By the provider | Requests routed to that provider |

## Platform rate limits

Each workspace is limited to a fixed number of requests per minute based on its subscription. When the limit is reached, requests are rejected with `429 Too Many Requests` until the 60-second window resets.

| Plan | Requests per minute |
| - | - |
| Free (Pay as you go without a payment method on file) | 20, and 50 per day |
| Pay as you go | 100 |
| Enterprise | 1500, higher by arrangement |

* Limits use a **fixed 60-second window** that starts with the first request, the same window that applies to budget requests-per-minute limits.
* Requests routed through a provider integration key or to a private model count toward these limits like any other request. See BYOK billing.
* Enterprise plans can arrange higher per-minute limits with **Toqan Router**.
* On-premise deployments are licensed rather than metered: plan-based limits do not apply. A single system-wide cap can be enforced with the `ORQ_SYSTEM_RPM_LIMIT` environment variable.

Platform limit rejections return `429` with a `Retry-After` header and the `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` headers.

## Budget limits

[Budgets](/docs/ai-gateway/budgets.md) apply configured limits to a named target. A budget defines one or more limits: **Cost** in USD, **Tokens**, and **Requests per minute**. See [Budgets](/docs/ai-gateway/budgets.md) for how to configure them.

Requests per minute always uses a 60-second window that starts with the first request, **independent of the reset period**. A monthly budget's `50 req/min` still allows 50 requests in any single minute, and the counter resets 60 seconds after the first request in the window, not at month end. The reset period (Daily, Weekly, Monthly, Yearly, One-time) applies to cost and token limits only.

### Limits on an API key

API keys do not carry limit fields of their own. Set cost, token, or requests-per-minute limits on a key by creating a [Budget](/docs/ai-gateway/budgets.md) scoped to that **API Key**. The key's remaining capacity is visible in the budget's detail page, and its cost and token capacity in the `X-RateLimit-*-Cost` and `X-RateLimit-*-Tokens` response headers.

> [!NOTE]
>
> The unsuffixed `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` headers report the plan's platform rate limit on a successful request, not a budget's requests-per-minute limit, because the platform limiter writes them last. A budget's requests-per-minute values appear in these headers only on a `429` raised by that budget. Read budget request consumption from the budget's detail page instead.

Legacy API keys, created before the current unified key model, do not support budget-based cost, token, or rate limits. Create a current API key and scope a [Budget](/docs/ai-gateway/budgets.md) to it instead.

## Multiple limits on one request

A request can match several budgets at once: for example, a budget scoped to the workspace and another scoped to the calling API key. Every matching budget is enforced, and each tracks its own usage. The most restrictive applicable limit binds. See [Budget levels and interaction](/docs/ai-gateway/budgets.md#budget-levels-and-interaction) for the full rules and worked examples.

## Provider rate limits

The upstream provider enforces its own rate and concurrency limits on the account behind the provider integration. The gateway does not place requests in a queue: there is no queue depth, queue position, or queue timeout to configure.

When the provider returns a rate-limit or other retryable error:

* The gateway holds the request open for the retry backoff only. It waits for the `Retry-After` interval the provider returns, and falls back to a default backoff when none is present.
* With a [retry configuration](/docs/ai-gateway/features/retries.md) on the request or agent, it retries up to the configured count inside the same request.
* With a fallback chain, an exhausted retry moves to the next model.
* If every attempt fails, the provider error is returned to the caller as the response.

## The 429 response

When any limit is exceeded, the gateway returns `429 Too Many Requests` with an OpenAI-compatible error body. Budget rejections carry `scope_kind`, `scope_target_id`, and `dimension`:

```json Budget rejection (requests per minute) theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "error": {
    "message": "Rate limit exceeded. Maximum requests allowed per minute.",
    "type": "rate_limit_error",
    "param": null,
    "code": "requests_per_minute_exceeded",
    "scope_kind": "workspace",
    "scope_target_id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
    "dimension": "requests"
  }
}
```

The `code` and `dimension` identify the exceeded limit:

| Code | Dimension | Limit |
| - | - | - |
| `rate_limit_exceeded` | (absent) | Platform rate limit (subscription plan) |
| `requests_per_minute_exceeded` | `requests` | Budget requests per minute |
| `cost_budget_exceeded` | `cost` | Budget cost |
| `token_budget_exceeded` | `tokens` | Budget tokens |

`scope_kind` and `scope_target_id` identify which budget rejected the request and are present only on budget rejections. The `message` text varies by limit type; use the `code` field for programmatic matching.

### Rate limit headers

Rate limit headers are emitted per dimension, and each group of three is present only when that dimension applies to the request. A response therefore carries some of these headers, not all of them. Headers appear on successful requests (showing remaining capacity) as well as on rejections.

| Header | Meaning | When present |
| - | - | - |
| `X-RateLimit-Limit` | Requests per minute allowed by the plan's platform rate limit | On every gateway request |
| `X-RateLimit-Remaining` | Requests left in the current window | On every gateway request |
| `X-RateLimit-Reset` | Seconds until the window resets (e.g. `42s`) | On every gateway request |
| `X-RateLimit-Limit-Tokens` | Token limit | Only when a matching budget sets a token limit |
| `X-RateLimit-Remaining-Tokens` | Tokens left in the current period | Only when a matching budget sets a token limit |
| `X-RateLimit-Reset-Tokens` | Seconds until the token counter resets (e.g. `42s`) | Only when a matching budget sets a token limit |
| `X-RateLimit-Limit-Cost` | Cost limit in USD | Only when a matching budget sets a cost limit |
| `X-RateLimit-Remaining-Cost` | Cost remaining in the current period (in USD) | Only when a matching budget sets a cost limit |
| `X-RateLimit-Reset-Cost` | Seconds until the cost counter resets (e.g. `42s`) | Only when a matching budget sets a cost limit |
| `Retry-After` | Seconds until the rejecting limit resets, as a plain integer (e.g. `42`). The `X-RateLimit-Reset*` headers use the `42s` format instead | Rejections only |

Two cases drop headers that the table otherwise lists as always present. The unsuffixed `X-RateLimit-*` triplet is omitted when the request carries no workspace context, and in on-premise deployments unless `ORQ_SYSTEM_RPM_LIMIT` is set. `Retry-After` is omitted when a rejected budget never resets on a clock, such as a **One-time** budget.

### Retries and fallbacks

`429` is retryable. The gateway's [Retries](/docs/ai-gateway/features/retries.md) feature retries on `429` by default with exponential backoff and honors the `Retry-After` header, and [fallbacks](/docs/ai-gateway/features/retries.md#fallbacks) route to a backup model when the primary is rate-limited. Retries run inside the gateway on a single incoming request (the platform rate limiter counts inbound client requests, not upstream calls), so they do not consume additional platform or budget quota.

## See also

> [card] [Budgets](/docs/ai-gateway/budgets.md)
>
> Create budgets with cost, token, and requests-per-minute limits and configure alerts.

> [card] [Budget levels](/docs/ai-gateway/budgets.md#budget-levels-and-interaction)
>
> How budgets at different levels interact when several apply to the same request.

> [card] [API Keys](/docs/ai-gateway/configuration/api-keys.md)
>
> Create and manage **AI Gateway** API keys, then scope a budget to cap usage.

> [card] [Fallbacks & Retries](/docs/ai-gateway/features/retries.md)
>
> Retry rate-limited requests with backoff and route to fallback models.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.