429 слишком много запросов: что это означает и как обрабатывать его

API возвращает 429 Too Many Requests, когда приложение отправляет больше запросов, чем API позволяет в течение определенного периода времени. Сам запрос корректен. Вы отправили его слишком часто, поэтому API отклонил его. Если вы подождете и отправите его снова, обычно это удается. Ответ часто содержит Retry-After заголовок, который указывает, как долго ждать. Дополнительные сведения см. в RFC 6585, разделе 4.

Каждый API реализует ограничения частоты запросов по-разному. Код состояния, заголовки и текст ошибки различаются, поэтому код, который обрабатывает один API правильно, может неправильно обработать следующий API.

API Status Как определить, сколько времени ждать Остерегайтесь
GitHub 403 или 429 retry-after, если указано, в противном случае x-ratelimit-remaining (в секундах эпохи UTC), когда x-ratelimit-reset равно 0, в противном случае — не менее 1 минуты Это может быть 403 ограничение скорости или отсутствие разрешения. Читайте заголовки, чтобы отличить их друг от друга.
OpenAI 429 retry-after Некоторые ошибки 429, например credit_balance_exhausted, означают, что повторная попытка не поможет. Проверьте error.code.
Anthropic 429 retry-after Ограничение расходов 429 не имеет retry-after и продолжает завершаться с ошибкой до возобновления доступа. Перегруженный API возвращает 529, а не 429.
Microsoft Graph 429 Retry-After (секунд) Ограничения различаются в зависимости от службы, например SharePoint и Outlook.

Обработка 429

  1. Решите, следует ли повторить попытку вообще. Если ошибка говорит, что квота, кредиты или лимит расходов исчерпаны, повторная попытка не поможет. Сообщите пользователю и уведомьте себя.
  2. Подождите столько, сколько требует API. Если в ответе указано Retry-After, подождите столько времени. Это либо количество секунд, либо дата HTTP. Если API использует заголовки ограничения скорости, например GitHubx-ratelimit-reset, подождите до времени сброса.
  3. В противном случае отступите. Без указания API повторите попытку с экспоненциальной задержкой и случайным jitter и остановитесь после нескольких попыток.
  4. Расскажите пользователю, что происходит. «Занят, повтор через 5 секунд» лучше, чем спиннер, который никогда не заканчивается.
  5. Подождите перед следующей ошибкой 429. Если API отправляет заголовки ограничения частоты запросов, используйте оставшееся число, чтобы регулировать частоту запросов.
async function fetchWithRetry(url, options, attempts = 3) {
  for (let attempt = 1; ; attempt++) {
    const response = await fetch(url, options);
    if (response.status !== 429 || attempt === attempts) {
      return response;
    }
    const retryAfter = response.headers.get('retry-after');
    const waitMs = retryAfter
      ? (isNaN(retryAfter) ? new Date(retryAfter) - Date.now() : retryAfter * 1000)
      : 2 ** attempt * 1000 + Math.random() * 1000;
    await new Promise(resolve => setTimeout(resolve, Math.max(waitMs, 0)));
  }
}

Многие пакеты SDK автоматически повторяют запросы при ошибке 429. Например, OpenAI Python SDK по умолчанию выполняет 2 повторные попытки, а стандартный обработчик устойчивости .NET выполняет 3 повторные попытки и учитывает Retry-After. Когда у SDK заканчиваются попытки повтора, ваш код получает ошибку, поэтому ему по-прежнему нужен план обработки.

Проверка того, что приложение обрабатывает 429

Вы редко видите 429 во время разработки. API работает быстро, вы единственный пользователь, и тестовые данные небольшие. Таким образом, способ проверки обработки 429 определяет, найдёте ли вы ошибки раньше, чем ваши пользователи.

Approach Что вы найдете Чего вам не хватает
Ожидание продакшена Реальные сбои Все, пока пользователь не нажмёт на него
Создайте мок API в тестах или позвольте ИИ-агенту для программирования написать мок Выполняется ли ветвь повторных попыток Реальные коды состояния, заголовки и тела ошибок API, а также политика повторных попыток вашего SDK. Вашему приложению также требуется переключатель только для тестирования для доступа к mock-сервису.
Вызывайте реальный API до тех пор, пока API не начнет ограничивать частоту запросов Реальное поведение Вы не можете вызвать ошибку 429 по требованию, и вы используете реальную квоту
Перехватывайте реальный трафик приложения и возвращайте коды 429 по требованию Реальные URL-адреса, ваш реальный SDK и политика повторных попыток, а также собственный формат 429 API Ничего в приложении не изменяется, поэтому приложение не проверяет код в изоляции. Оставьте модульные тесты для этого.

Попробуйте его в вашем приложении

Dev Proxy перехватывает запросы приложения к выбранным API и возвращает ответы 429 с заголовками и форматом ошибок самого API, а приложение продолжает вызывать реальные URL-адреса. Он также сообщает вам, когда ваше приложение повторяет попытку до истечения времени Retry-After.

Скачайте preset для API, которое вызывает ваше приложение, и запустите с ним Dev Proxy:

devproxy config get github-rate-limiting
devproxy --config-file "~dataFolder/configs/github-rate-limiting/.devproxy/devproxyrc.json"
API Preset
GitHub github-rate-limiting
OpenAI openai-throttling
Anthropic anthropic-throttling
Microsoft Graph (OneDrive и SharePoint: /drive, /shares, /sites) microsoft-graph-rate-limiting

Затем запустите приложение как обычно и посмотрите, что он делает. Чтобы установить прокси-сервер разработки, см. статью "Настройка прокси-сервера разработки".

Дальнейшие действия

См. также