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

# Rate Limiting

> How the platform throttles API requests, and how to tune the limits

The platform rate-limits requests to protect the backend from overload and abuse. Limits are enforced in Redis with a sliding window and are **configurable per endpoint group** — you can tune them without a code change.

## How it works

* Each protected endpoint belongs to a **rate-limit group** (for example `create_run_async`, `kb_search`, `sandbox_create`, `tables_write`, `deployments_write`, or `default`).
* A group's limit is a **rule**: *N requests per time window* (`runs` per `delta_seconds`).
* The counter is keyed by the caller — the **API key's workspace** for API-key endpoints, or the **user** for authenticated app endpoints — so one tenant's traffic never consumes another's budget.
* When a caller exceeds the limit, the request is rejected with **HTTP 429** and a **`Retry-After`** header telling the client how long to wait.

<Info>
  Limits are stored in the database and cached, so changes take effect without a
  redeploy. The in-code defaults are the fallback used if the stored config can't
  be read.
</Info>

## Tuning the limits

Tenant admins configure the limits in the app under **Settings → Platform → Rate limits**. Each endpoint group shows its current allowance; adjust the number of requests and the window per group.

Typical groups you'll see:

| Group                                  | Guards                                          | Why it's separate                               |
| -------------------------------------- | ----------------------------------------------- | ----------------------------------------------- |
| `create_run_async` / `create_run_sync` | Starting workflow runs                          | Runs are expensive; sync runs hold a connection |
| `kb_search`, `upload_document`         | Knowledge-base search / ingestion               | Vector search and ingestion are heavy           |
| `sandbox_create` / `sandbox_exec`      | Creating sandboxes vs. running commands in them | Booting a sandbox is much heavier than exec     |
| `tables_query` / `tables_write`        | Table SQL vs. writes                            | Arbitrary SQL is the expensive path             |
| `deployments`, `triggers`, `insights`  | Channel/trigger/analytics reads and writes      | Scoped so a burst on one doesn't starve others  |
| `default`                              | Everything without a dedicated group            | Catch-all baseline                              |

<Tip>
  Raise the groups your integration hammers (e.g. `tables_query` for a reporting
  job) rather than a blanket increase — the per-group split exists so one hot path
  can't exhaust the whole budget.
</Tip>

## Handling 429 in clients

Any client should treat a `429` as "back off and retry after the `Retry-After` interval." The [Python SDK](/sdk/concepts/authentication) already does this for you — it retries `429`s with bounded exponential backoff that honors `Retry-After`, and raises `RateLimitedError` only after exhausting its retries. In other languages, read the `Retry-After` header and retry rather than hammering.

<Note>
  Rate limiting is one layer. Front the platform with your own WAF / gateway for
  IP-level protection and DDoS mitigation — see
  [Inbound networking](/deployment/networking/inbound).
</Note>
