Rate limits
Rate limits keep the Kalle API fast for everyone. Each workspace has limits per model, on both requests and tokens per minute.
How limits work
- Limits apply per workspace, so all keys in a workspace share them.
- Each model has its own limits. Busy traffic on Kalle Turbo does not slow down Kalle Turbo Ultra.
- Requests and tokens are counted separately. You can hit the token limit with a few large requests.
- Your current limits are shown in Kalle API in the Appmake console.
Headers
Every response tells you where you stand:
| Header | Meaning |
|---|---|
x-ratelimit-limit-requests | Requests allowed per minute for this model. |
x-ratelimit-remaining-requests | Requests left in the current window. |
x-ratelimit-reset-requests | When the request window resets, as an ISO 8601 time. |
x-ratelimit-limit-tokens | Tokens allowed per minute for this model. |
x-ratelimit-remaining-tokens | Tokens left in the current window. |
x-ratelimit-reset-tokens | When the token window resets, as an ISO 8601 time. |
retry-after | Only on 429 responses: the seconds to wait before you try again. |
When you hit a limit
Kalle answers with status 429 and an error of the type rate_limit_error. Wait for the number of seconds in retry-after, then try again. Without the header, back off exponentially with some randomness, so many clients do not retry at the same moment:
async function withRetry(send: () => Promise<Response>, attempts = 5): Promise<Response> {
for (let attempt = 0; ; attempt++) {
const response = await send();
if (response.status !== 429 || attempt === attempts - 1) return response;
const retryAfter = Number(response.headers.get("retry-after"));
const wait = retryAfter > 0 ? retryAfter * 1000 : 2 ** attempt * 500 + Math.random() * 250;
await new Promise((resolve) => setTimeout(resolve, wait));
}
}Staying under your limits
- Watch the
remainingheaders and slow down before you reach zero. - Set
max_tokensclose to what you need. The token limit counts it before the answer is written. - Use Kalle Turbo for high-volume, simple work and save the bigger models for the requests that need them.
- Queue background jobs and run them at a steady pace instead of all at once.