Rate limit API: как рассчитать и избежать блокировки
- Rate limit считается по формуле: лимит = N / T, где N — макс. запросов за окно T секунд.
- Окна бывают fixed (проще, но есть burst) и sliding (равномернее, но сложнее).
- Алгоритмы: Token Bucket (рекомендуется), Leaky Bucket, Fixed Window, Sliding Window Log.
- Best practice: возвращать заголовки X-RateLimit-Remaining и Retry-After.
- На 2026 год типичные лимиты для публичных API: 100–5000 запросов в минуту.
- Базовая формула и единицы измерения
- Стратегии: fixed vs sliding window
- Пример расчёта с пошаговыми цифрами
- Примеры кода: Token Bucket на Python и Node.js
- Подводные камни и частые ошибки
- Сравнение: rate limit, churn, retention, conversion
- Как отладить rate limit: заголовки и логирование
- Частные случаи: burst, distributed rate limit, API key per user
- Заключение: считайте лимиты до того, как получите 429
Базовая формула и единицы измерения
Rate limit (ограничение скорости) задаётся тремя числами: N — максимальное число запросов, T — временное окно (обычно секунды или минуты), и стратегия сброса (fixed или sliding). Формула для расчёта лимита на секунду:
Но в реальности вы оперируете целыми числами. Если API разрешает 1000 запросов в час, то средний R ≈ 0.278 req/s, но пиковые нагрузки не должны превышать N в любом окне T. Единицы: N — безразмерное (штуки), T — время в секундах. Типовые окна:
- Секунда — высоконагруженные внутренние API (лаги 1-100 ms);
- Минута — публичные REST API (типично 60–3000 запросов);
- Час — соцсети и карты (1000-10000 запросов/час).
Всегда уточняйте единицы окна в документации — перепутав минуту и час, получите 429.
Стратегии: fixed vs sliding window
Fixed Window — каждое окно начинается в фиксированные моменты времени (например, 00:00, 00:01). Простота, но есть риск burst: в конце окна и начале следующего можно отправить 2N запросов подряд. Пример: лимит 100 req/min, в 10:00:59 — 100 запросов, в 10:01:00 — ещё 100. Итого 200 за 2 секунды.
Sliding Window — окно скользит по времени (например, последние 60 секунд). Плавное, затратнее памяти (история временных меток). Нет burst-всплесков.
На практике для высоконагруженных систем используют Token Bucket (сглаживает burst, прост в реализации).
Пример расчёта с пошаговыми цифрами
Дано: API Яндекс.Карт (тестовый example) — лимит 50 запросов в минуту, окно 60 сек, fixed window. Нужно обработать 200 запросов. Сколько минут потребуется?
- Лимит на окно: N = 50, T = 60 с.
- Первый burst: 50 запросов за 1 сек → ожидание 59 сек до следующего окна.
- Каждое окно даёт 50 запросов. Для 200 нужно 200/50 = 4 полных окна.
- Минимальное время: 4 * 60 = 240 секунд (4 минуты).
- На практике требуются задержки. Добавим sleep(60 секунд) после каждого окна → итого 4 минуты.
Формула для времени ожидания при fixed window для N запросов: T_total = ceil(N / limit_per_window) * window_seconds.
Если sliding window, время меньше: примерно T_total = (N - 1) * (window_seconds / limit_per_window) + 1 ≈ 239 секунд.
Примеры кода: Token Bucket на Python и Node.js
# Python: Token Bucket
import time
from threading import Lock
class TokenBucket:
def __init__(self, rate, burst):
self.rate = rate # токенов в секунду
self.burst = burst # максимум токенов
self.tokens = burst
self.last_refill = time.monotonic()
self.lock = Lock()
def consume(self, tokens=1):
with self.lock:
now = time.monotonic()
elapsed = now - self.last_refill
self.tokens = min(self.burst, self.tokens + elapsed * self.rate)
self.last_refill = now
if self.tokens < tokens:
return False
self.tokens -= tokens
return True
# Использование
bucket = TokenBucket(rate=10, burst=20)
for i in range(25):
if bucket.consume():
print(f"Запрос {i} выполнен")
else:
print(f"Запрос {i} отклонён")
time.sleep(0.05)
// Node.js: Token Bucket с setInterval
class TokenBucket {
constructor(rate, burst) {
this.rate = rate;
this.burst = burst;
this.tokens = burst;
this.lastRefill = Date.now();
setInterval(() => {
const now = Date.now();
const elapsed = (now - this.lastRefill) / 1000;
this.tokens = Math.min(this.burst, this.tokens + elapsed * this.rate);
this.lastRefill = now;
}, 10);
}
consume(tokens = 1) {
if (this.tokens >= tokens) {
this.tokens -= tokens;
return true;
}
return false;
}
}
// Использование
const bucket = new TokenBucket(10, 20);
for (let i = 0; i < 25; i++) {
if (bucket.consume()) console.log(`Запрос ${i} выполнен`);
else console.log(`Запрос ${i} отклонён`);
}
В обоих случаях rate — токены в секунду, burst — максимальный накопленный. Для rate 10 и burst 20 можно выдержать пик 20 запросов мгновенно, затем не более 10 в секунду.
- 1Получить 429
Прочитай статус-код и Retry-After.
- 2Проверить заголовки
X-RateLimit-* покажут остаток и сброс.
- 3Идентифицировать окно
Узнай, fixed или sliding.
- 4Вычислить время ожидания
Используй формулу: ceil(N / limit) * window.
- 5Применить стратегию
Token Bucket — лучшая для гашения burst.
- 6Логировать и мониторить
Записать в лог и повторно отправить.
Подводные камни и частые ошибки
- Путаница с окном. Если в документации написано "1000 req/hour", а вы реализуете окно 1 час — норм. Но многие API используют скользящее окно (sliding), и фиксированное даст ложные 429.
- Не учитывать Retry-After. При 429 сервер часто возвращает заголовок Retry-After в секундах. Игнорируя его, вы получаете бан.
- Token Bucket без проверки очереди. Если несколько потоков одновременно вызывают consume, нужна блокировка (lock/mutex), иначе race condition.
- Переполнение при больших rate. Не забывайте про ограничение burst снизу (≥1), иначе tokens станет отрицательным.
- Неверный мониторинг. Логи только ошибок — мало. Нужно логировать и успешные запросы с заголовками X-RateLimit-Remaining.
Важно: на 2026 год многие API уже перешли на sliding window. Проверьте документацию. Используйте наш Калькулятор rate limit API, чтобы быстро прикинуть лимиты.
🧠 Проверьте понимание rate limit
1. Что такое sliding window?
2. Какой алгоритм лучше сглаживает burst?
3. Если лимит 100 req/min, а вам нужно 350, минимальное время ожидания при fixed window?
4. Какой заголовок указывает, сколько запросов осталось?
Сравнение: rate limit, churn, retention, conversion
Rate limit — лишь один из метрик API. Если вы строите продукт, полезно считать и пользовательские метрики. Сравним:
| Метрика | Что измеряет | Формула | Инструмент |
|---|---|---|---|
| Rate limit | Запросов в секунду/минуту | N/T | Калькулятор rate limit API |
| Churn rate | Отток пользователей за период | UserLost / UserStart × 100% | Калькулятор churn rate |
| Retention rate | Возврат пользователей | UserReturned / UserStart × 100% | Калькулятор retention rate |
| Conversion rate | Конверсия визит→цель | Goal / Visitors × 100% | Калькулятор CR |
Как отладить rate limit: заголовки и логирование
Первый шаг при 429 — проверить HTTP-заголовки ответа. Стандарт RFC 6585 рекомендует:
- X-RateLimit-Limit — лимит (max запросов за окно);
- X-RateLimit-Remaining — сколько осталось;
- X-RateLimit-Reset — Unix timestamp сброса окна.
Пример отладки на Python с логированием:
import requests
def api_call(url):
resp = requests.get(url, headers={'User-Agent': 'my-cool-app'})
# Логируем заголовки
if 'X-RateLimit-Remaining' in resp.headers:
print(f"Remaining: {resp.headers['X-RateLimit-Remaining']}")
if resp.status_code == 429:
retry_after = resp.headers.get('Retry-After', '1')
print(f"429 — ждём {retry_after} сек")
time.sleep(int(retry_after))
return api_call(url)
return resp.json()
Если API не возвращает эти заголовки, можно оценивать лимит эмпирически, отправляя запросы до первого 429 и замеряя интервал.
Для тестирования своей реализации используйте Калькулятор rate limit API — введите параметры, получите время ожидания.
Частные случаи: burst, distributed rate limit, API key per user
Burst-лимит. Многие API разрешают короткий всплеск запросов, но со штрафом. Пример: 10 req/s с burst 20. В Token Bucket это решается параметром burst. Формула: actual_speed = min(rate, burst / time).
Distributed rate limit. Если несколько серверов, каждый знает только свою часть. Используйте Redis с atomic INCR и TTL (fixed window) или Sorted Set (sliding window). Пример на Redis:
-- Фиксированное окно через INCR
local key = KEYS[1] .. ':' .. math.floor(tonumber(ARGV[1])/60)
local limit = tonumber(ARGV[2])
local current = redis.call('GET', key) or 0
if (tonumber(current) + 1) > limit then
return 0
else
redis.call('INCR', key)
redis.call('EXPIRE', key, 60)
return 1
end
Per-user rate limit. Используйте ключ вида rate_limit:user_id:epohh_minute. В токен-бакете — отдельный bucket на пользователя.
Заключение: считайте лимиты до того, как получите 429
Расчёт rate limit — базовая защита вашего приложения и сервера. Используйте Калькулятор rate limit API, чтобы заранее прикинуть, сколько синхронных запросов уложатся в лимит. А для метрик пользователей — Калькулятор churn rate, Калькулятор retention rate и Калькулятор CR.
🧮 Посчитайте сами — инструменты по теме
🧭 Разделы по теме
Частые вопросы
Что такое rate limit простыми словами?
Rate limit — ограничение на количество запросов к API за определённое время. Например, не более 10 запросов в секунду. Если превысить, сервер вернёт ошибку 429.
Как рассчитать rate limit для API?
Нужно узнать из документации лимит (N запросов за T секунд). Средняя скорость — N/T, но пики не должны превышать N в любом окне. Используйте формулу: минимальное время = ceil(нужно_запросов / N) * T.
Чем отличается fixed window от sliding window?
При fixed window лимит сбрасывается в фиксированные моменты (например, каждую минуту). При sliding window учитываются запросы за последние N секунд, что даёт более равномерное распределение.
Что такое Token Bucket?
Это алгоритм, где накапливаются токены с постоянной скоростью. Запрос тратит токен. Если токенов нет — запрос отклоняется. Плюс: можно накопить burst до максимального количества.
Какие заголовки возвращает API при rate limit?
Стандарт: X-RateLimit-Limit (лимит), X-RateLimit-Remaining (осталось), X-RateLimit-Reset (время сброса), Retry-After (секунд до повтора при 429).
Как обойти rate limit?
Соблюдайте лимит, используйте кэширование, паузы между запросами, распределяйте нагрузку по ключам API, увеличивайте burst. Попытки игнорировать приведут к бану.
Что делать, если API не возвращает заголовки rate limit?
Экспериментально определите лимит, отправляя запросы до первого 429. Засеките интервал между 429 и успешными запросами. Или обратитесь в поддержку API.
Как реализовать rate limit на своей стороне?
Используйте библиотеки (например, pyrate-limiter) или напишите свой Token Bucket. Для распределённых систем используйте Redis с INCR и TTL.
Источники и нормативные документы
- RFC 6585 - Additional HTTP Status Codes
- MDN Web Docs - Rate limiting
- Google Cloud - Rate limiting patterns
- AWS - API Gateway throttling