# Rate limits

Set how fast each repo may start runs and spend. Bursts above the limit are turned away at the edge, before they cost anything.

![Requests arrive in a burst. The ones within the limit pass through at a steady pace; the rest are turned away at the edge and told when to try again.](/illos/rate-limit.svg)

## Set a limit

Limits live in `kestrel.yaml`, so they are reviewed like any other change to the repo.

```yaml kestrel.yaml
limits:
  runs_per_minute: 20
  spend_per_day: 50     # dollars
```

| Limit | What happens when it is reached |
|---|---|
| `runs_per_minute` | New runs are refused with `429` and a `Retry-After` header |
| `spend_per_day` | New runs wait in the [queue](/runs/queue) until the next day |

## What a refused run looks like

```http
HTTP/1.1 429 Too Many Requests
Retry-After: 18
Content-Type: application/json

{ "error": { "type": "rate_limited", "message": "acme/web-app may start 20 runs a minute", "retry_after": 18 } }
```

The SDKs read `Retry-After` and wait before trying again, up to `maxRetries` times. See [Retries](/runs/retries).

## Workspace limits

Every workspace also has a ceiling of 600 API requests a minute, across all keys. It is there to stop a loop in a script from flooding the API, and few teams ever reach it.

> [!TIP]
> Give a noisy repo its own low `spend_per_day`. It can then never use up the whole team's [monthly cap](/billing#spend-limits).
