Skip to content
← Все статьи

Стратегии ограничения частоты запросов для веб-API

rate limiting контролирует, сколько запросов клиент может сделать к API документацию за определённый период. Защищает инфраструктуру от злоупотреблений, обеспечивает справедливое использование и предотвращает монополизацию ресурсов.

Зачем нужен rate limiting

  • Защита от DDoS: ограничивает влияние объёмных атак
  • Справедливость: один пользователь не истощает ресурсы для других
  • Контроль затрат: ограничение дорогих операций (БД, сторонние API)
  • Монетизация API: тарифы лимиты (free, pro, business)
  • Стабильность: защита от случайных всплесков (сломанные retry-циклы, штормы краулеров)

Алгоритмы

Fixed Window

Подсчёт запросов в фиксированных окнах (например, за минуту). Сброс счётчика в начале окна.

  • Плюс: простая реализация, мало памяти
  • Минус: проблема всплеска — 100 запросов в 0:59 и 100 в 1:00 = двойной лимит

Sliding Window Log

Хранит таймстамп каждого запроса. Считает за последние N секунд.

  • Плюс: точный, без всплесков
  • Минус: много памяти

Sliding Window Counter

Гибрид: фиксированные окна с пропорциональным весом предыдущего. Если прошло 30% текущего окна — считаем 70% предыдущего + 100% текущего.

  • Плюс: плавный, мало памяти, без всплесков
  • Минус: приближённый (но очень точный на практике)

Token Bucket

Ведро наполняется токенами с постоянной скоростью. Каждый запрос потребляет токен. Пустое ведро = отказ. Позволяет контролируемые всплески.

  • Плюс: допускает всплески, плавный
  • Минус: чуть сложнее реализация

Leaky Bucket

Запросы попадают в очередь и обрабатываются с фиксированной скоростью. Полная очередь = отброс.

  • Плюс: максимально ровная скорость
  • Минус: добавляет задержку, нет всплесков

Реализация на Redis

-- Sliding window counter (Lua-скрипт)
local key = KEYS[1]
local limit = tonumber(ARGV[1])
local window = tonumber(ARGV[2])
local now = tonumber(ARGV[3])

redis.call('ZREMRANGEBYSCORE', key, 0, now - window)
local count = redis.call('ZCARD', key)

if count < limit then
    redis.call('ZADD', key, now, now .. math.random())
    redis.call('EXPIRE', key, window)
    return 0  -- разрешено
else
    return 1  -- ограничено
end

HTTP-заголовки ответа

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1679529600
Retry-After: 30

При ограничении — 429 Too Many Requests:

HTTP/1.1 429 Too Many Requests
Retry-After: 30
{"error": "Превышен лимит запросов. Повторите через 30 секунд."}

По чему ограничивать

  • IP: просто, но общие IP (NAT) затрагивают нескольких пользователей
  • API-ключ: точнее для аутентифицированных API
  • Аккаунт: per-user лимиты независимо от IP
  • Эндпоинт: разные лимиты (логин: 5/мин, поиск: 30/мин)
  • Комбинация: IP + endpoint для анонимных, user + endpoint для авторизованных

Лучшие практики

  • Информативные заголовки: лимит, остаток, время сброса
  • Код 429: не 403 и не 503
  • Дифференциация по тарифу: Free 50/день, Pro 5000/день
  • Агрессивный лимит на логин: 5-10 попыток/мин против брутфорса
  • Graceful degradation: кешированные ответы вместо жёсткого отказа
  • Логирование: мониторьте кто и почему попадает под лимиты

Заключение

Rate limiting — необходимая инфраструктура для любого API. Начните со sliding window counter, реализуйте per-key лимиты и всегда сообщайте лимиты через заголовки. Хорошая реализация защищает сервис, сохраняя хороший developer experience.

Проверьте ваш сайт прямо сейчас

Проверить безопасность сайта →
Другие статьи: Безопасность
Безопасность
HSTS и список предзагрузки: полное руководство по внедрению
16.03.2026 · 139 просм.
Безопасность
Письма уходят в спам: причины и как исправить
23.06.2026 · 46 просм.
Безопасность
Content Security Policy (CSP) — полное руководство по настройке
12.03.2026 · 134 просм.
Безопасность
Безопасность API: лучшие практики защиты
11.03.2026 · 150 просм.