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

# Rate limiting

To ensure availability, stability, and fair usage for all users, the tipee API enforces rate limiting on all requests.

## Token bucket

Rate limiting is based on a **token bucket** mechanism. Each tenant has a bucket of tokens that is consumed by requests and replenished continuously over time.

<CardGroup cols={2}>
  <Card title="Pool of 500 tokens..." icon="bucket">
    Maximum token pool size at your disposal.
  </Card>

  <Card title="... replenishing at 4 tokens / second" icon="arrows-rotate">
    Refill rate — your pool continuously replenishes at this pace.
  </Card>
</CardGroup>

Each API request consumes one token from the bucket. When the bucket is empty, further requests are rejected until enough tokens have been replenished. These limits apply to all endpoints available in this documentation.

## Concurrency limits

In addition to rate limiting, the API limits the number of requests that can be processed simultaneously for a given tenant.

| Parameter                   | Value                   |
| --------------------------- | ----------------------- |
| Maximum concurrent requests | 32 per tenant           |
| Queue capacity              | 128 additional requests |

When all concurrent slots are in use, additional requests are held in a queue. If the queue is also full, the API responds immediately with an error.

These are upper bounds. During periods of high load, effective concurrency may be reduced to ensure fairness across tenants. Reaching these limits is also likely to affect human users interacting with tipee on the same instance.

<Warning>In practice, we recommend keeping concurrent requests below 10.</Warning>

## Response headers

Every API response includes headers describing your current rate limit status:

| Header                      | Description                                         |
| --------------------------- | --------------------------------------------------- |
| `X-RateLimit-Limit`         | Maximum number of requests allowed                  |
| `X-RateLimit-Remaining`     | Requests remaining before the limit is reached      |
| `X-RateLimit-Rate-Amount`   | Number of requests replenished per interval         |
| `X-RateLimit-Rate-Interval` | Duration of each replenishment interval, in seconds |

Example:

```
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 456
X-RateLimit-Rate-Amount`: 4
X-RateLimit-Rate-Interval: 1
```

<Tip>We strongly recommend using these headers in your application to proactively manage your request frequency and avoid hitting the limit.</Tip>

## Exceeding the limit

When the limit is reached, the API responds with **HTTP 429 Too Many Requests** and includes a `Retry-After` header indicating seconds to wait before a request can be accepted:

```
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 0
X-RateLimit-Rate-Amount: 4
X-RateLimit-Rate-Interval: 1
Retry-After: 1
```

<Warning>You should not attempt to retry the request until the `Retry-After` duration has passed.</Warning>

## Best practices

<CardGroup cols={2}>
  <Card title="Use response headers to self-throttle" icon="gauge-high">
    Monitor `X-RateLimit-Remaining` and reduce your request rate as it decreases. This is more reliable than reacting to `429` errors after the fact.
  </Card>

  <Card title="Limit concurrency" icon="arrows-split-up-and-left">
    Keep parallel requests below 10 to avoid contention and minimize impact on human users of the same tipee instance.
  </Card>

  <Card title="Respect Retry-After" icon="hourglass-half">
    When you receive a `429` response, always wait for the full duration specified in the header before retrying.
  </Card>

  <Card title="Spread requests over time" icon="wave-sine">
    A steady flow of requests uses the refill rate more efficiently than large bursts followed by idle periods.
  </Card>

  <Card title="Implement exponential backoff" icon="rotate">
    For transient errors (`5xx`) or repeated rate limit responses, increase the delay between retries rather than retrying immediately.
  </Card>
</CardGroup>
