Что такое Rate Limiting?

Rate limiting контролирует, сколько запросов клиент может сделать к API за определённое временное окно. Он защищает серверы от злоупотреблений, обеспечивает справедливое использование и предотвращает DDoS-атаки. Как тестировщик, вам нужно проверить, что rate limit-ы корректно реализованы и что API ясно сообщает о лимитах.

Почему Rate Limiting важен

Без rate limiting один клиент может перегрузить сервер:

  • Баг в мобильном приложении, отправляющий запросы в бесконечном цикле
  • Злоумышленник, пытающийся скачать все данные
  • Неправильно настроенная интеграция с тысячами вызовов в секунду
  • Brute-force атаки на endpoint-ы аутентификации

Алгоритмы Rate Limiting

Фиксированное окно (Fixed Window)

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

Скользящее окно (Sliding Window)

Отслеживает запросы за скользящее временное окно. Точнее фиксированного — если вы отправили 80 запросов за последние 60 секунд, у вас осталось 20.

Token Bucket

Токены добавляются в корзину с фиксированной скоростью. Каждый запрос потребляет один токен. Если корзина пуста, запрос отклоняется. Корзина имеет максимальную ёмкость, допуская всплески.

Leaky Bucket

Запросы попадают в очередь (корзину) и обрабатываются с постоянной скоростью. При переполнении новые запросы отклоняются.

АлгоритмОбработка всплесковТочностьСложность
Фиксированное окноВсплески на границахНизкаяНизкая
Скользящее окноПредотвращает всплескиВысокаяСредняя
Token BucketКонтролируемые всплескиВысокаяСредняя
Leaky BucketБез всплесковВысокаяСредняя

Заголовки Rate Limit

Большинство API сообщают о rate limit-ах через заголовки:

HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 73
X-RateLimit-Reset: 1625097600
Retry-After: 30
ЗаголовокЗначение
X-RateLimit-LimitМаксимум запросов в окне
X-RateLimit-RemainingОставшиеся запросы в текущем окне
X-RateLimit-ResetUnix timestamp сброса окна
Retry-AfterСекунды ожидания перед повтором (при 429)

Тестирование заголовков Rate Limit

Для каждого успешного ответа проверяйте:

  1. X-RateLimit-Limit присутствует и соответствует документации
  2. X-RateLimit-Remaining уменьшается на 1 с каждым запросом
  3. X-RateLimit-Reset — валидная будущая метка времени
  4. Значения согласованы между последовательными запросами

Тестирование применения Rate Limit

Базовый тест применения

Отправляйте запросы в быстрой последовательности:

import requests
import time

url = "https://api.example.com/data"
headers = {"Authorization": "Bearer token"}
results = []

for i in range(110):  # Превысить лимит 100/мин
    response = requests.get(url, headers=headers)
    results.append({
        "request": i + 1,
        "status": response.status_code,
        "remaining": response.headers.get("X-RateLimit-Remaining")
    })

# Проверить: первые 100 — 200, остальные — 429

Тестовые сценарии

СценарийОжидаемое поведение
Нормальное использование200 с правильным remaining
Точно на лимите200 для последнего разрешённого запроса
На один выше лимита429 с Retry-After
После ожидания сброса200 с полным лимитом
Разные endpoint-ыМогут иметь отдельные лимиты
Разные auth-токеныУ каждого пользователя свои лимиты
Без аутентификацииОбычно более строгие лимиты по IP

Тест восстановления

После достижения лимита:

  1. Проверить, что 429 содержит Retry-After
  2. Подождать указанное время
  3. Отправить ещё запрос — должен быть 200
  4. Проверить сброс X-RateLimit-Remaining

Лимиты по endpoint vs. глобальные

Некоторые API имеют разные лимиты по endpoint-ам:

  • Аутентификация: 5 запросов/минуту
  • Чтение: 1000 запросов/минуту
  • Запись: 100 запросов/минуту
  • Поиск: 30 запросов/минуту

Проверяйте, что лимиты применяются к каждому endpoint-у отдельно.

Распространённые баги Rate Limiting

БагКак обнаружить
Лимиты не применяютсяПревысить лимит — всё 200
Неверный remainingОтслеживать X-RateLimit-Remaining
Неверное время сбросаСравнить timestamp с реальным поведением
Нет Retry-After при 429Проверить заголовки 429
Лимиты сбрасываются при ошибкеВызвать 400, проверить счётчик

Практическое упражнение

  1. Тестируйте лимиты GitHub API: GitHub допускает 60 запросов/час без аутентификации. Отслеживайте заголовки rate limit.
  2. Определите тип окна: Фиксированное или скользящее — отправляйте всплески на границах окон.
  3. Тест восстановления: Достигните лимита, дождитесь Retry-After, проверьте восстановление.
  4. Задокументируйте лимиты: Создайте таблицу всех rate limit-ов тестового API.

Ключевые выводы

  • Rate limiting защищает API от злоупотреблений — его тестирование критически важно для продакшна
  • Основные алгоритмы: фиксированное окно, скользящее окно, token bucket и leaky bucket
  • Всегда проверяйте точность и согласованность заголовков rate limit
  • Тестируйте полный цикл: нормальное использование, достижение лимита, получение 429, восстановление
  • Лимиты по endpoint-ам, пользователям и IP могут различаться — тестируйте каждый