COMRAD404 / HOWTO

Как настроить rate limiting для API

Пошаговая инструкция по настройке rate limiting для API в NGINX, AWS API Gateway, Cloudflare и Envoy: как выбрать точку ограничения, безопасно включить правило и проверить 429/503.

Понадобится

От 20 до 90 минут для базовой настройки, в зависимости от стека
  • Доступ к NGINX, AWS API Gateway, Cloudflare WAF или Envoy
  • Понимание маршрута API, который нужно ограничить
  • Доступ к логам, аналитике или Security Analytics для оценки request rate
  • Возможность отправить тестовые запросы и проверить коды ответа

Результат. После выполнения этой инструкции вы настроите rate limiting для API в одном из четырёх распространённых стеков — NGINX, AWS API Gateway, Cloudflare WAF или Envoy — и проверите, что ограничение реально срабатывает, не ломая легитимный трафик на старте.

Короткий ответ. Настраивать rate limiting лучше не с произвольного числа запросов, а с трёх решений: где именно ограничивать трафик, какой ключ использовать для учёта запросов и как включить правило безопасно. Для NGINX используйте limit_req_zone и limit_req; для AWS API Gateway — throttling и quotas; для Cloudflare — expression-based rate limiting rules в WAF; для Envoy — local или global rate limit filter.

  • ⏱️ Время: от 20 до 90 минут для базовой настройки, в зависимости от стека.
  • 🎯 Сложность: средняя.
  • 💰 Стоимость: зависит от выбранного стека, региона и тарифа; для AWS и Cloudflare проверяйте актуальные условия на официальных страницах, для self-hosted NGINX и Envoy учитывайте инфраструктурные затраты.
  • 🛠️ Что потребуется: доступ к NGINX, AWS API Gateway, Cloudflare WAF или Envoy; понимание маршрута API, который нужно ограничить; доступ к логам или аналитике; способ отправить тестовые запросы.
  • 📌 Актуальность: официальные источники проверены на 2026-08-15. Для AWS API Gateway и Cloudflare в источниках нет единого номера «версии интерфейса», поэтому ориентируйтесь на дату проверки источников. Для NGINX зафиксировано, что limit_req_dry_run задокументирован начиная с 1.17.1.

Практический вердикт. Если у вас один reverse proxy, начните с NGINX. Если API уже стоит за публичным edge, сначала смотрите Cloudflare и запускайте правило через Log first. Если API полностью живёт в AWS, применяйте возможности API Gateway, но не считайте usage plans жёстким лимитом или инструментом контроля расходов. Если у вас несколько прокси или service mesh, используйте Envoy global rate limiting. Редакционное ограничение: в аудированном пакете источников нет полных и одинаково детализированных console path для всех провайдеров, поэтому ниже приведены только официально подтверждённые примитивы, ограничения и способы проверки.

Как выбрать, где ограничивать запросы

Стек Что использовать Когда подходит Ключевое ограничение
NGINX ngx_http_limit_req_module, директивы limit_req_zone и limit_req Self-hosted API и reverse proxy у края инфраструктуры Ограничение локально для развёртывания NGINX, если не добавлять внешнюю координацию
AWS API Gateway REST API Usage plans и API keys, throttling и quotas на уровне API или метода Managed AWS API с потребителями по ключам AWS прямо предупреждает: это best-effort control, а не жёсткий лимит и не механизм cost control
AWS API Gateway HTTP API Throttling по модели token bucket Простой managed throttling в AWS без отдельного reverse proxy Account-level throttling действует по Region, а региональные квоты различаются
Cloudflare WAF Expression-based rate limiting rules Публичный API на edge, защита login/API endpoints, анти-абьюз Доступность зависит от WAF plan; account-level rulesets требуют Enterprise
Envoy Local rate limit filter или global rate limit filter Распределённые сервисы, service mesh, единая политика на несколько proxy Global-режим требует внешний rate-limit service; сложность выше, чем у local limiting

Пошаговая настройка rate limiting для API

  1. Шаг 1. Выберите точку enforcement. Сначала решите, где лимит должен применяться: на reverse proxy, на managed gateway, на edge CDN/WAF или в сервисной сети. Выбирайте одно основное место для первичного ограничения, иначе вы получите пересекающиеся лимиты и не поймёте, какой слой возвращает ошибку.

    Ожидаемый результат: у вас есть один основной слой, который будет первым ограничивать запросы.

  2. Шаг 2. Зафиксируйте точный путь и тип трафика. Не ограничивайте весь домен целиком, если вам нужен только один endpoint. Cloudflare прямо рекомендует сначала проверить целевой path и pattern трафика; для аутентифицированного трафика в официальных best practices упоминается API Discovery как способ понять request rate.

    Ожидаемый результат: вы знаете конкретный path и понимаете, ограничиваете ли вы публичный, аутентифицированный или внутренний трафик.

  3. Шаг 3. Начните с безопасного режима запуска. Если стек это поддерживает, сначала включайте режим без немедленной блокировки. Для NGINX используйте limit_req_dry_run; для Cloudflare официальный workflow рекомендует сначала подобрать лимит через Request rate analysis в Security Analytics, затем развернуть правило с действием Log, а уже после этого переходить к Block или Challenge.

    Ожидаемый результат: вы можете увидеть, кого затронет правило, до включения жёсткой блокировки.

  4. Шаг 4. Настройте NGINX, если лимит нужен на self-hosted proxy. Официальный модуль ngx_http_limit_req_module использует модель leaky bucket. Базовые директивы — limit_req_zone и limit_req; для поведения очереди и всплесков документированы burst, nodelay и delay. Если вы хотите сначала оценить влияние правила, добавьте limit_req_dry_run.

    http {
        limit_req_zone $binary_remote_addr zone=api_limit:<ZONE_SIZE> rate=<RATE>;
    
        server {
            location <PATH> {
                limit_req zone=api_limit burst=<BURST> nodelay;
                limit_req_dry_run on;
            }
        }
    }

    Если вы не переопределяли статус ответа, по умолчанию отклонённые запросы получат HTTP 503. Практически это значит: сначала оцените нормальную скорость запросов, затем подставьте свои значения в <RATE>, <BURST> и <ZONE_SIZE>.

    Ожидаемый результат: у вас есть рабочая конфигурация NGINX с лимитом на нужный путь и понятным поведением при всплесках.

  5. Шаг 5. Настройте AWS API Gateway для REST API, если используете usage plans. Для REST API AWS документирует throttling и quotas через usage plans и API keys. Эти ограничения можно применять на уровне API или метода. Критически важно: AWS прямо предупреждает, что usage plans — это best-effort targets; их нельзя считать жёсткими лимитами и нельзя использовать как гарантированный контроль затрат.

    Ожидаемый результат: потребители, привязанные к API key и usage plan, получают rate/quota policy, но вы осознанно не полагаетесь на неё как на абсолютный стоп-сигнал.

  6. Шаг 6. Настройте AWS API Gateway для HTTP API, если вам нужен управляемый throttling без usage plans. Для HTTP APIs AWS документирует throttling по модели token bucket. Запросы сверх настроенной скорости могут получать HTTP 429. Отдельно учитывайте региональность: account-level throttling enforced per Region, а квоты различаются — для многих регионов по умолчанию указано 10,000 requests per second, для ряда перечисленных регионов — 2,500 requests per second.

    Ожидаемый результат: вы настроили throttling с пониманием, что итоговое поведение зависит не только от route, но и от региональных account-level квот.

  7. Шаг 7. Настройте Cloudflare WAF для публичного edge API. В Cloudflare rate limiting rules являются expression-based и применяются через WAF. Официальная последовательность такая: сначала используйте Request rate analysis в Security Analytics, затем проверьте правильность target path, после этого разверните правило с действием Log и только потом переводите его в Block или Challenge. Учтите, что доступность возможностей зависит от WAF plan, а account-level rate limiting rulesets требуют Enterprise.

    Ожидаемый результат: правило затрагивает только нужный endpoint и сначала даёт наблюдаемость, а не внезапную блокировку клиентов.

  8. Шаг 8. Настройте Envoy, если лимит должен работать в распределённой среде. Для локального ограничения используйте local rate limit filter: он работает по модели token bucket, по умолчанию действует на один процесс Envoy, но может быть scoped по route или virtual host. Когда bucket пуст, Envoy возвращает HTTP 429 и выставляет заголовок x-envoy-ratelimited. Если нужен единый лимит на несколько proxy или сервисов, используйте global rate limit filter, который обращается к внешнему rate-limit service. Для этого режима важно знать: over-limit requests тоже получают HTTP 429, а при failure_mode_deny=true сбой внешнего сервиса лимитов может привести к HTTP 500. В репозитории reference implementation также задокументированы служебные endpoints /healthcheck и /json для проверки сервиса.

    Ожидаемый результат: вы выбрали между простым per-process limiting и более сложным global limiting с внешним сервисом.

Как проверить, что всё работает

Сделайте короткий burst тестов по целевому маршруту. Шаблон для ручной проверки можно запустить из shell, заменив плейсхолдеры:

for i in $(seq 1 <REQUEST_COUNT>); do
  curl -i https://<HOST><PATH>
done

Что считать успешной проверкой

  • NGINX: после отключения dry_run запросы сверх лимита по умолчанию получают HTTP 503, если вы не меняли reject status.
  • AWS API Gateway HTTP API: запросы сверх настроенной скорости могут получать HTTP 429.
  • AWS API Gateway REST API: проверьте поведение потребителей, привязанных к usage plan и API key, но помните, что throttling и quotas для usage plans описаны AWS как best-effort.
  • Cloudflare: в режиме Log сначала анализируйте события в Security Analytics; переводите правило в Block или Challenge только после подтверждения path и нормального traffic pattern.
  • Envoy local/global: ограниченные запросы получают HTTP 429; для local filter дополнительно смотрите заголовок x-envoy-ratelimited.
  • Envoy global service: отдельно проверьте доступность сервиса лимитов через /healthcheck и /json.
curl -i http://<RATELIMIT_SERVICE>/healthcheck
curl -i http://<RATELIMIT_SERVICE>/json

Если вы видите коды 429 или 503 не там, где ожидали, вернитесь к шагам выбора path и rollout mode: чаще всего проблема не в алгоритме, а в том, что правило повесили слишком широко или ввели слишком рано без анализа трафика.

Частые ошибки и исправления

  • Ошибка: вы ограничили весь домен, хотя хотели только один endpoint.
    Решение: сузьте правило до точного path. Для Cloudflare это официальный первый шаг перед enforcement.
  • Ошибка: вы сразу включили жёсткую блокировку и задели легитимных клиентов.
    Решение: сначала применяйте безопасный режим — limit_req_dry_run в NGINX или Log first в Cloudflare.
  • Ошибка: вы считаете AWS usage plans абсолютной защитой от всплесков или перерасхода.
    Решение: учитывайте официальное предупреждение AWS: это best-effort control, а не hard limit и не инструмент cost control.
  • Ошибка: вы ждёте, что локальный лимит автоматически станет глобальным на все инстансы.
    Решение: помните, что NGINX и Envoy local ограничивают трафик локально для своего развёртывания или процесса. Для общего распределённого лимита нужен внешний координирующий слой, например Envoy global rate limit service.
  • Ошибка: вы включили failure_mode_deny=true в Envoy global без плана отказоустойчивости.
    Решение: заранее решите, что важнее при сбое внешнего сервиса лимитов: fail-open или fail-closed. Иначе сбой rate-limit service может обернуться HTTP 500.
  • Ошибка: вы не учли региональные ограничения AWS API Gateway.
    Решение: перед rollout сверяйте Region-specific quotas: account-level throttling в API Gateway enforced per Region, а значения квот различаются.

Безопасность и ограничения

  • Rate limiting не заменяет аутентификацию, авторизацию и прикладные guardrails. Если вы защищаете AI-приложение, сочетайте лимиты с проверками входа и политиками безопасности.
  • Для AWS API Gateway pricing и поведение по лимитам зависят от сервиса, региона и модели API. Не используйте устаревшие таблицы или сторонние summaries — сверяйте официальную страницу pricing и квот.
  • Для Cloudflare состав доступных действий и правил зависит от WAF plan; account-level rate limiting rulesets требуют Enterprise.
  • Для NGINX важны операционные детали: shared memory zone, а также выбор между burst, nodelay и delay. Неправильная комбинация легко делает лимит либо слишком мягким, либо слишком агрессивным.
  • Для Envoy global complexity выше, чем у local limiting: нужен внешний rate-limit service, а в типовой схеме — ещё и хранилище состояния. Это хороший выбор только там, где действительно нужен единый лимит на несколько прокси.
  • Редакционная оговорка: в этом материале нет универсального «правильного числа запросов в секунду». Официальные источники подтверждают механизмы и ограничения, но не дают безопасного значения для каждого API. Подбирайте его только по собственным analytics и traffic pattern.

Что делать дальше

Источники

Вопросы и ответы

Какой код ответа считать нормальным признаком сработавшего лимита?

Зависит от стека. У NGINX по умолчанию это HTTP 503, если вы не меняли статус отклонения. У AWS API Gateway HTTP API и у Envoy documented поведение — HTTP 429 при превышении лимита. У Envoy local дополнительно выставляется x-envoy-ratelimited.

Можно ли использовать AWS usage plans как жёсткий лимит и защиту от перерасхода?

Нет. AWS прямо пишет, что throttling и quotas в usage plans — это best-effort targets. Их не стоит использовать как гарантированный hard limit или как механизм cost control.

Как безопасно включать rate limiting в продакшене?

Сначала измерьте трафик и подтвердите точный path, затем включайте режим без немедленной блокировки. Для NGINX это limit_req_dry_run, для Cloudflare — запуск правила с действием Log перед переходом к Block или Challenge.

Когда нужен Envoy global, а когда достаточно local rate limiting?

Local подходит, когда достаточно ограничивать трафик в рамках одного процесса Envoy или конкретного route/virtual host. Global нужен, когда лимит должен быть единым для нескольких proxy или сервисов, но за это вы платите дополнительной операционной сложностью.

Что проверять после включения лимита кроме кода ответа?

Проверьте, что правило срабатывает только на нужный маршрут, что оно не затрагивает легитимный трафик и что у вас есть наблюдаемость. Для Cloudflare используйте Security Analytics, для Envoy global дополнительно проверьте /healthcheck и /json у rate-limit service.

Шаги

HOW-TO
  1. Выберите точку enforcement

    | Определите, где лимит будет применяться первым: NGINX, AWS API Gateway, Cloudflare WAF или Envoy. Не дублируйте стартовую политику сразу на нескольких слоях без ясной цели.

  2. Зафиксируйте точный path и тип трафика

    | Ограничивайте конкретный endpoint, а не весь домен. Для публичного edge и аутентифицированного трафика сначала изучите реальный traffic pattern.

  3. Запустите правило в безопасном режиме

    | Для NGINX используйте limit_req_dry_run, для Cloudflare — Log first после Request rate analysis. Это снижает риск ложных срабатываний.

  4. Настройте NGINX при self-hosted схеме

    | Используйте limit_req_zone и limit_req, а поведение всплесков задавайте через burst, nodelay и delay. Помните, что default reject status — 503.

  5. Настройте AWS API Gateway REST API

    | Применяйте usage plans и API keys для throttling и quotas на уровне API или метода, но учитывайте официальное ограничение AWS: это best-effort control.

  6. Настройте AWS API Gateway HTTP API

    | Используйте throttling по модели token bucket. Запросы сверх лимита могут получать 429, а account-level throttling действует по Region.

  7. Настройте Cloudflare WAF rate limiting rule

    | Выберите expression-based rule, проверьте path через Security Analytics и переведите правило из Log в Block или Challenge только после валидации.

  8. Настройте Envoy local или global rate limiting

    | Local filter подходит для per-process лимита и возвращает 429 с x-envoy-ratelimited. Global filter требует внешний rate-limit service и нуждается в отдельной проверке через /healthcheck и /json.

Источники

SOURCES

Вопросы и ответы

FAQ
Какой код ответа считать нормальным признаком сработавшего лимита?

Зависит от стека. У NGINX по умолчанию это HTTP 503, если вы не меняли статус отклонения. У AWS API Gateway HTTP API и у Envoy documented поведение — HTTP 429 при превышении лимита. У Envoy local дополнительно выставляется x-envoy-ratelimited.

Можно ли использовать AWS usage plans как жёсткий лимит и защиту от перерасхода?

Нет. AWS прямо пишет, что throttling и quotas в usage plans — это best-effort targets. Их не стоит использовать как гарантированный hard limit или как механизм cost control.

Как безопасно включать rate limiting в продакшене?

Сначала измерьте трафик и подтвердите точный path, затем включайте режим без немедленной блокировки. Для NGINX это limit_req_dry_run, для Cloudflare — запуск правила с действием Log перед переходом к Block или Challenge.

Когда нужен Envoy global, а когда достаточно local rate limiting?

Local подходит, когда достаточно ограничивать трафик в рамках одного процесса Envoy или конкретного route/virtual host. Global нужен, когда лимит должен быть единым для нескольких proxy или сервисов, но за это вы платите дополнительной операционной сложностью.

Что проверять после включения лимита кроме кода ответа?

Проверьте, что правило срабатывает только на нужный маршрут, что оно не затрагивает легитимный трафик и что у вас есть наблюдаемость. Для Cloudflare используйте Security Analytics, для Envoy global дополнительно проверьте /healthcheck и /json у rate-limit service.

Читайте также

LINKS