HTTP 429 Too Many Requests — код ответа RFC 6585 (2012), возвращаемый сервером при превышении клиентом rate limit — ограничения частоты запросов. Защищает сервер от злоупотреблений, DDoS-атак и некорректно настроенных клиентов, которые отправляют избыточное число запросов за короткий период.
Заголовки при 429
Корректный ответ 429 включает заголовок Retry-After и опциональные заголовки информации о лимите:
Retry-After: 60— подождать 60 секунд перед повтором.Retry-After: Wed, 26 Jun 2024 10:30:00 GMT— подождать до конкретного времени.X-RateLimit-Limit: 100— максимальное число запросов в периоде.X-RateLimit-Remaining: 0— осталось запросов в текущем периоде.X-RateLimit-Reset: 1719398400— unix-timestamp сброса счётчика.
Стандарт IETF Draft «RateLimit Header Fields for HTTP» (2023) предлагает унифицировать эти заголовки как RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.
Алгоритмы rate limiting
- Fixed Window — N запросов за период T (100 req/min). Прост в реализации, но уязвим к burst-атаке на границе временного окна: 100 запросов в конце одного окна + 100 в начале следующего = 200 запросов за 2 секунды.
- Sliding Window Log — хранит timestamps всех запросов за последние T секунд. Точный, но памятеёмкий.
- Sliding Window Counter — гибрид: считает запросы в текущем окне + взвешенный остаток из предыдущего. Точный и дешёвый по памяти.
- Token Bucket — токены добавляются с постоянной скоростью (r токенов/с), каждый запрос тратит 1 токен. Разрешает burst при накопленных токенах. Использует Nginx (через burst параметр).
- Leaky Bucket — запросы добавляются в очередь (bucket), обрабатываются с постоянной скоростью. Сглаживает bursts, но добавляет задержку.
Реализация в Nginx
Nginx поддерживает rate limiting через модуль ngx_http_limit_req_module:
http {
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $http_x_api_key zone=apikeyzone:10m rate=100r/s;
server {
location /api/ {
limit_req zone=api burst=20 nodelay;
limit_req zone=apikeyzone burst=200 nodelay;
limit_req_status 429;
}
}
}
rate=10r/s — 10 запросов в секунду. burst=20 — вспышка до 20 запросов без задержки. nodelay — не ставить в очередь, сразу отдавать 429. Зона apikeyzone — отдельный лимит для авторизованных клиентов с API-ключом.
История
Код 429 стандартизирован в RFC 6585 (апрель 2012 года). До этого API-провайдеры использовали нестандартные коды: Twitter возвращал 420 (нестандартный), некоторые провайдеры — 403. RFC 6585 унифицировал подход. С ростом публичных API в 2010-х rate limiting стал обязательным требованием безопасности и защиты от злоупотреблений.
Rate limiting в хостинге
На VPS-серверах 429 применяется для защиты API и форм от автоматизированных запросов. Redis — стандартный backend для счётчиков rate limiting: атомарный INCR + EXPIRE на ключ вида ratelimit:IP:minute. Cloudflare WAF и Anti-DDoS сервисы предоставляют готовые правила rate limiting на сетевом уровне — до достижения origin-сервера. При настройке rate limiting важно учитывать легитимных пользователей за корпоративным NAT: один IP, но сотни пользователей. Ограничивать по API-ключу или учётной записи эффективнее, чем только по IP.
429 в API-интеграциях
При интеграции с внешними API (OpenAI, Yandex API, Telegram Bot API) код 429 означает исчерпание квоты. Правильная обработка: exponential backoff с jitter — каждая повторная попытка удваивает паузу с добавлением случайной составляющей. Пример на Python:
import time, random
def api_call_with_retry(func, max_retries=5):
for attempt in range(max_retries):
response = func()
if response.status_code != 429:
return response
retry_after = int(response.headers.get('Retry-After', 2 ** attempt))
time.sleep(retry_after + random.uniform(0, 1))
raise Exception("Rate limit exceeded after retries")