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

# Rate limits and concurrency

> The limits on Mage API use: generations in flight per account, active keys, request body and input sizes, and how to design a client around them.

The main limit is concurrency: how many generations an account may have queued or running at once. There is no charge for a refused request.

## Generations in flight

An account may have 20 generations in flight at once, counting the API and the app together. A submit past that cap is refused with `429 too_many_requests` and nothing is charged. The cap can be changed for an account; write to [mage@mage.space](mailto:mage@mage.space) with your use case.

```json theme={null}
{
  "error": {
    "code": "too_many_requests",
    "message": "At most 20 generations may be in flight at once for this account; 20 are running now."
  }
}
```

The check reads the count at submit time. A burst of simultaneous submits can therefore slightly exceed the cap; every admitted generation is still paid for as usual.

## Other limits

| Limit                       | Value                                         |
| --------------------------- | --------------------------------------------- |
| Active API keys per account | 10                                            |
| Request body                | 4.5 MB                                        |
| One media input             | 100 MB, whether fetched, decoded, or uploaded |
| Fetching one input URL      | 60 seconds and 3 redirects                    |
| `Idempotency-Key`           | 1 to 255 characters                           |
| Results and inputs          | Kept 30 days                                  |

Requests may also be rate limited at the edge during bursts. Treat any `429` as a signal to wait, whatever its body.

## Designing around the limits

* Keep a worker pool no larger than your cap and submit from it, rather than submitting everything at once and handling the refusals.
* Poll on a separate schedule from submission, with backoff, so status reads do not compete with submits.
* Store `request_id` as soon as a submit returns; the status link is how you recover from anything that happens afterwards.
* Send an `Idempotency-Key` with every submit so a retry never pays twice.
