Обработка rate limits
Как безопасно обрабатывать 429, текущие лимиты запросов и токенов, throttling и лимит повторов в GonkaGate.
Сначала прочитайте error.code, а потом решайте, нужен ли retry для 429.
В GonkaGate insufficient_quota означает, что для этого запроса не хватает prepaid USD balance. rate_limit_exceeded и transfer_agent_capacity_reached обычно временные. Держите эту развилку в одном общем обработчике ретраев, чтобы все вызовы вели себя одинаково.
Решите, нужен ли retry
| Если пришло | Что это обычно значит | Что делать |
|---|---|---|
429 + insufficient_quota | Для этого запроса не хватает prepaid USD balance | Не ретрайте. Покажите состояние баланса или пополнения и повторяйте запрос только после появления средств. |
429 + rate_limit_exceeded | Трафик упёрся в лимит запросов | Учитывайте Retry-After, если он пришёл, и ретрайте с небольшим лимитом повторов. |
429 + transfer_agent_capacity_reached | Временное давление по capacity | Подождите, аккуратно повторите запрос и держите число повторов маленьким. |
429 без известного кода | Обычно это всё ещё временный throttling или pressure по capacity | Сначала трактуйте это как временный throttling, но логируйте полный ответ, если сбой повторяется. |
Текущие лимиты аутентифицированных запросов к моделям
Для POST /v1/chat/completions и других аутентифицированных /v1/* запросов к моделям GonkaGate проверяет несколько rate-limit buckets. Если исчерпан любой из них, срабатывает самый строгий исчерпанный bucket.
| Scope | Лимит запросов | Burst и concurrency |
|---|---|---|
Обычный API-ключ (gp-...) | 600 RPM | 200 запросов за 10 секунд и 50 concurrent requests |
| Обычный API-ключ + source IP | 600 RPM | 200 запросов за 10 секунд |
| Аккаунт-владелец | 3,000 RPM | 1,000 запросов за 10 секунд и 200 concurrent requests |
| Source IP | 3,000 RPM | 1,000 запросов за 10 секунд |
| Разные source IP для одного обычного ключа | 200 IP в час | Допускает обычный multi-region и serverless IP churn |
| Разные обычные ключи с одного source IP | 200 ключей в час | Важно, когда много customer keys выходят через один backend IP |
RPM означает requests per minute. Burst — это отдельное 10-секундное окно запросов.
TPM означает estimated tokens per minute. Сейчас GonkaGate учитывает token windows для телеметрии и rate-limit headers: 2,000,000 TPM для обычного API-ключа и key+IP scopes, и 10,000,000 TPM для аккаунта-владельца и source IP scopes. Сами token windows сегодня не блокируют запросы; 429 rate_limit_exceeded могут возвращать request, burst, concurrency, distinct и cooldown checks.
Стандартные buckets выше относятся к обычному разнообразному трафику. Повторяющиеся синтетические запросы, особенно много минимальных или почти одинаковых prompts на один и тот же key, source IP и model, могут включить behavioral cooldown даже тогда, когда RPM, burst и concurrency остаются внутри опубликованных лимитов. Такие ответы сохраняют 429 rate_limit_exceeded и включают Retry-After.
Повторяющиеся локальные 429 из-за request limit могут также включить короткий cooldown для key+IP, key или аккаунта-владельца. Значение по умолчанию — 3 подходящих локальных request-limit блока за 60 секунд. Активный cooldown сохраняет тот же контракт 429 rate_limit_exceeded и выставляет Retry-After по TTL cooldown.
Это лимиты трафика, а не лимиты расходов. Per-key USD limit, настроенный через управление API-ключами, ограничивает расходы конкретного обычного ключа, но prepaid USD balance аккаунта остаётся общим для аккаунта.
Лимиты public playground
POST /v1/public/chat/completions использует отдельные public-traffic guards. Anonymous playground requests ограничены 20 запросами в минуту и 50 запросами в час на browser principal, а также такими же 20 запросами в минуту и 50 запросами в час на source IP. Concurrency для anonymous public playground — 2 in-flight requests на principal.
Общий public guard допускает 10,000 RPM, 10,000,000 estimated TPM и 1,000 in-flight requests для всего public playground traffic. Когда включён authenticated user-billed playground mode, такие запросы используют /v1/* API-key buckets выше и отдельный playground guard на 4 in-flight requests per authenticated principal.
Используйте один общий обработчик ретраев
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
export async function requestWithRateLimitHandling(
makeRequest: () => Promise<Response>,
maxRetries = 3
): Promise<Response> {
for (let attempt = 0; attempt <= maxRetries; attempt += 1) {
const response = await makeRequest();
if (response.status !== 429) {
return response;
}
const body = await response
.clone()
.json()
.catch(() => null);
const errorCode = body?.error?.code;
if (errorCode === "insufficient_quota") {
throw new Error("insufficient_quota");
}
if (attempt === maxRetries) {
throw new Error("retry_budget_exhausted");
}
const retryAfterSeconds = Number(response.headers.get("Retry-After") ?? "0");
const waitMs =
retryAfterSeconds > 0 ? retryAfterSeconds * 1000 : Math.min(1000 * 2 ** attempt, 8000);
await sleep(waitMs);
}
throw new Error("retry_budget_exhausted");
}Эта базовая политика делает четыре вещи: ветвится по error.code, останавливается на insufficient_quota, учитывает Retry-After и ограничивает число повторов.
Сначала читайте эти поля
- HTTP status
429 error.codeв JSON bodyRetry-After, если сервер точно говорит, сколько ждатьx-ratelimit-*, если клиент их видит, чтобы логировать текущий лимит, оставшийся запас и окно сбросаx-request-idдля повторяющихся сбоев или эскалации в саппорт
Поле error.message используйте только как человекочитаемый контекст. Не стройте retry-логику по тексту сообщения.
Частые ошибки
- Считать любой
429обычным throttling. В GonkaGateinsufficient_quota— это состояние биллинга, а не повод для backoff. - Игнорировать
Retry-After, если он пришёл. Обычно это приводит к синхронным retry и новому throttling. - Прятать
insufficient_quotaза автоматическими ретраями. Остановитесь и покажите состояние биллинга или пополнения. - Думать, что у каждого сгенерированного
gp-...ключа есть отдельная account-level квота. Per-key buckets отдельные, но ключи одного аккаунта GonkaGate всё равно делят aggregate bucket этого аккаунта. - Считать синтетический load test с одинаковыми минимальными prompts доказательством обычной sustained throughput. Используйте репрезентативные разные prompts или заранее согласуйте окно теста с support.
- Давать воркерам, cron-job’ам или batch-трафику ретраить бесконечно. Держите лимит повторов маленьким и защищайте пользовательский трафик.
Смотрите также
- Ключи Management API, чтобы программно создавать обычные
gp-...ключи и задавать per-key USD-лимиты расходов. - Обработку ошибок API в GonkaGate, если нужна та же логика retry-or-stop для
401,403,5xxи других non-429ошибок. - Страница цен для правил предоплаченного USD-баланса за
insufficient_quota. - Создать chat completion для точного контракта
POST /v1/chat/completions.