Лимиты API: как рассчитать и не превысить
- Стандартный лимит большинства публичных API на 2026 год — 100-1000 запросов в минуту.
- В формуле лимитов критичны три параметра: max_requests, window_size и burst_size.
- Fixed window даёт 2x запас, если не учитывать перекрытие окон; sliding window точнее.
- Токен-бакет (Token Bucket) — наиболее производительный алгоритм для реального времени.
- Для расчёта лимитов используйте формулу: L = (R × W) + B, где R — запросов/сек, W — окно в сек, B — burst.
- Что такое лимит API и почему он нужен?
- Основные алгоритмы ограничения запросов
- Формула расчёта лимита и burst-запаса
- Пошаговый пример: расчёт лимита для API погоды
- Частые ошибки при работе с лимитами
- Как упростить расчёт: онлайн-калькулятор
- Интеграция расчёта лимитов в код: примеры
- Как отлаживать проблемы с лимитами?
- Когда и как увеличить лимит API?
Что такое лимит API и почему он нужен?
Лимит API (rate limit) — это максимальное количество запросов, которое ваш клиент может отправить за определённый интервал времени. API-провайдеры защищают свои серверы от перегрузок и несправедливого потребления. Например, сервис погоды может разрешать 60 запросов в минуту, а поисковый — 1000 запросов в час. Если превысить лимит, вы получите HTTP-статус 429 Too Many Requests с заголовком Retry-After.
Понимание лимитов критично для стабильности вашего приложения. Без расчёта можно легко попасть в DDoS-подобную ситуацию на своей же интеграции. На 2026 год типовые лимиты публичных API:
- Twitter API: 300 запросов/15 мин (v2)
- GitHub API: 5000 запросов/час (авторизованный)
- OpenAI API: зависит от модели — 3-60 RPM
Основные алгоритмы ограничения запросов
Существует несколько алгоритмов, используемых для rate limiting. Знание их механик поможет точнее проектировать клиентскую логику.
- Fixed Window (FWA): счётчик обнуляется каждые N секунд. Например, лимит 100 запросов в минуту — сброс в начале каждой минуты. Минус: burst в конце окна может удвоить нагрузку, если не контролировать.
- Sliding Window Log (SWL): хранит временные метки всех запросов. При новом запросе удаляются старые (вне окна). Точнее, но требует памяти O(n).
- Sliding Window Counter (SWC): комбинация фиксированных окон. Разбивает окно на более мелкие слоты, например, минуту — на 10 секундных сегментов.
- Token Bucket: выдача токенов с постоянной скоростью; burst-запросы возможны, пока есть запас. Используется в Redis-based решениях.
- Leaky Bucket: запросы ставятся в очередь; если очередь переполнена — отбрасываются. Сглаживает трафик, но не допускает burst.
Выбор алгоритма зависит от сценария. Для большинства веб-приложений достаточно Token Bucket — он даёт и сглаживание, и возможность всплесков.
Формула расчёта лимита и burst-запаса
Базовая формула для расчёта максимального числа запросов L в окне:
где R — разрешённая скорость (запросов в секунду), W — ширина окна (в секундах), B — burst-запас (дополнительные запросы сверх R×W). Burst позволяет обрабатывать временные пики без превышения долгосрочного лимита.
Пример: API позволяет 300 запросов в минуту. Это R=5 запр/с (300/60). W=60 с. Burst=20. Тогда L=5×60+20=320. Округлённый лимит — 320 запросов в минуту. На практике burst часто не указывается — его узнают из документации.
Если burst не объявлен, считайте B=0. Но в популярных API (GitHub, OpenAI) burst заложен неявно — например, GitHub разрешает ~5000 запр/час, но можно слать до 100 за раз без задержки. Проверяйте заголовки X-RateLimit-Remaining.
Пошаговый пример: расчёт лимита для API погоды
Допустим, ваш сервис использует WeatherAPI.com. В документации указано: 1000 запросов в день (суммарно). Рассчитаем:
- Определите окно: 1 день = 86400 секунд.
- R = 1000 / 86400 ≈ 0.0116 запр/с.
- Burst: если не указан, считаем 0. Но обычно есть burst — допустим, 50.
- L = 0.0116 × 86400 + 50 = 1000 + 50 = 1050 запросов.
Но для практического использования вам нужен минутный лимит, чтобы не слать 1000 запросов разом. Пересчитаем на минуту: 1000 запр/день ≈ 0.694 запр/мин. Если burst минутный — 50, то L_min = 0.694 × 60 + 50 ≈ 91.6. Округляем до 92. Значит, в минуту — 92 запроса.
При превышении лимита API вернёт 429. Используйте заголовки: X-RateLimit-Limit: 92, X-RateLimit-Remaining.
- 1Изучить документацию API
Найти параметры: скорость, burst, алгоритм.
- 2Выбрать алгоритм
Token Bucket для burst, Sliding Window для точности.
- 3Рассчитать L и burst по формуле
L = R×W + B. Использовать свой или онлайн калькулятор.
- 4Написать client-side middleware
Реализовать бакет/окно в коде интеграции.
- 5Тестировать с заголовками
Проверить, что Remaining не уходит в ноль.
- 6Мониторить и логировать
Собирать метрики 429, добавлять алерты.
Частые ошибки при работе с лимитами
- Игнорирование заголовков: не читаете Retry-After или X-RateLimit-Reset — и отправляете запросы раньше времени.
- Неверное окно: путаете скользящее окно с фиксированным. Фиксированное может дать сброс в середине секунды — и вы получите 429 даже при соблюдении средней скорости.
- Синхронная задержка: блокируете поток при ожидании — падает производительность. Используйте асинхронный семафор.
- Не учитываете несколько ключей: если у вас несколько API-ключей, общий лимит суммируется только если ключи привязаны к одному аккаунту. Иначе — лимиты отдельно.
- Жёсткие sleep(): в случае ошибки при повторных запросах используйте exponential backoff с jitter.
Проверьте документацию API: многие указывают лимит на ключ или на IP. Не путайте!
Как упростить расчёт: онлайн-калькулятор
Чтобы не мучиться с дробями и ручными вычислениями, используйте Калькулятор лимитов API. Он поддерживает все популярные алгоритмы (Token Bucket, Sliding Window, Fixed Window) и мгновенно выдаёт итоговое число запросов для любого окна.
Вам нужно ввести: RPS (запросов в секунду), размер окна и burst. Калькулятор покажет лимит L, а также порекомендует заголовки для кэширования. Это сэкономит время и снизит риск ошибки.
Также пригодится для отладки интеграций: выставьте целевое RPS и проверьте, не будет ли превышения.
Интеграция расчёта лимитов в код: примеры
Реализуем токен-бакет на Python. Следующий код будет поддерживать burst и равномерную скорость.
import time
class TokenBucket:
def __init__(self, rate, burst):
self.rate = rate # токенов в секунду
self.burst = burst # максимальный запас
self.tokens = burst
self.last_refill = time.time()
def consume(self, tokens=1):
now = time.time()
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
# Пример: 10 запросов в секунду, burst 20
bucket = TokenBucket(10, 20)
for _ in range(22):
if bucket.consume():
# отправляем запрос
pass
else:
time.sleep(0.1)
Аналогично для sliding window: храните список времен меток в deque.
from collections import deque
class SlidingWindow:
def __init__(self, limit, window):
self.limit = limit
self.window = window # в секундах
self.timestamps = deque()
def allow_request(self):
now = time.time()
# удаляем старые
while self.timestamps and self.timestamps[0] < now - self.window:
self.timestamps.popleft()
if len(self.timestamps) < self.limit:
self.timestamps.append(now)
return True
return False
Как отлаживать проблемы с лимитами?
- Анализируйте заголовки: используйте curl с -v, чтобы увидеть
X-RateLimit-Limit,Remaining,Reset. Например:curl -v https://api.github.com. Сравните с ожиданием. - Тестируйте на песочнице: многие API предоставляют тестовые эндпоинты без лимитов. Отлаживайте там.
- Логируйте: пишите в лог время каждого запроса и ответный код. При 429 засекайте Retry-After.
- Используйте mock-сервер: напишите простой Flask-сервер, который эмулирует rate limit. Это быстрее, чем долбиться к продакшену.
Не забывайте про Retry-After: игнорирование приводит к вееру ошибок. Он может быть в секундах или дате.
Когда и как увеличить лимит API?
Если вашему сервису нужно больше запросов, сделайте следующее:
- Проверьте тариф: часто лимиты растут с апгрейдом плана. Например, платный план GitHub даёт 15000 запр/час.
- Запросите увеличение: напишите в техническую поддержку, объясните нагрузку. Могут одобрить до 2-3x.
- Используйте несколько ключей: балансируйте между разными аккаунтами/ключами, если это не запрещено правилами.
- Кэшируйте ответы: уменьшите число реальных запросов. Установите TTL, соответствующий требованиям свежести.
Важно: не увеличивайте burst за счёт сокращения окна — это может нарушить SLA. Планируйте запас в 20-30% от максимального лимита для равномерности.
🧮 Посчитайте сами — инструменты по теме
🧭 Разделы по теме
Частые вопросы
Что делать, если API не присылает заголовки лимитов?
Проверьте документацию: возможно, лимит фиксированный и указан в портале. Пишите тестовый запрос раз в секунду до 429, затем используйте полученное max-число. Либо используйте каноничные значения: 60 запр/мин для публичных API.
Какой алгоритм лучше: Token Bucket или Sliding Window?
Token Bucket проще в реализации и допускает burst, но может превысить среднюю скорость на коротких интервалах. Sliding Window даёт строгие лимиты за счёт больших затрат памяти. Выбирайте по задаче: для burst-нагрузок — бакет, для строгих SLA — SW.
Что такое burst и как его найти?
Burst — максимальное количество запросов, которое можно отправить мгновенно, не дожидаясь пополнения. Обычно указывается в документации (например, 'burst 100'). Если не указан, можно вывести эмпирически, отправив серию запросов с интервалом 0 и увидев, когда придёт 429.
Как рассчитать лимит для нескольких API ключей?
Суммируйте лимиты, только если ключи принадлежат одному аккаунту и API разрешает объединение. Иначе каждый ключ имеет свой независимый лимит — не складывайте. Пример: у вас 2 ключа GitHub — каждый даёт 5000 запр/час. Нельзя слать 10000 с одного ключа.
Почему я получаю 429, хотя не превышаю лимит?
Возможно, у вас фиксированное окно и вы попадаете на конец окна. Проверьте время сброса (секунда 59). Или ваш клиент превышает burst. Также лимит может быть на IP, а не на ключ — проверьте документацию.
Какие заголовки нужно читать в ответе API?
Основные: X-RateLimit-Limit (лимит окна), X-RateLimit-Remaining (осталось), X-RateLimit-Reset (таймстемп сброса). Некоторые API отдают Retry-After (секунды до освобождения).
Как протестировать rate limiter локально?
Напишите простой Flask-сервер, который по маршруту /api отдаёт заголовки лимитов и 429 после N запросов. Затем запустите свой клиент против этого мока — так вы отловите логические ошибки без риска для продакшена.
Можно ли обойти лимиты API?
Технически — используя несколько ключей или прокси, но это нарушает ToS. Лучше запросить повышение лимита у провайдера или перейти на платный тариф.
Источники и нормативные документы
- GitHub REST API rate limiting documentation
- MDN: HTTP 429 Too Many Requests
- OpenAI rate limits documentation
- WeatherAPI.com documentation