2

Projetando um Rate Limiter Global: Guia Completo de System Design

Resumo: Um guia de arquitetura em nível de produção para construir rate limiting distribuído em APIs e microsserviços, cobrindo algoritmos, armazenamento de estado, trade-offs de consistência global, quotas por tenant, limites adaptativos, resistência a abuso e operação observável.

Publicado: Fevereiro 2026
Tempo de leitura: 80 minutos
Palavras-chave: #SystemDesign #RateLimiter #APIGateway #Quota #SistemasDistribuídos #Escalabilidade #Confiabilidade #EntrevistaTécnica


Às 09:00, seu tráfego está normal. Às 09:01, uma versão bugada do cliente dispara retries sem backoff. Às 09:02, um tenant enterprise inicia backfill massivo. Às 09:03, bots iniciam credential stuffing.

Sem rate limiting, tudo compartilha o mesmo colapso.

Com rate limiting fraco, usuários legítimos são bloqueados enquanto abuso continua passando.

Rate limiter sério não é só contador:

  • protege disponibilidade,
  • garante fairness,
  • aplica plano comercial,
  • limita custo operacional,
  • reduz blast radius.

Este guia detalha um desenho de nível senior para entrevistas e produção.


Sumário


Análise de Requisitos

Requisitos Funcionais

  1. Aplicar limite por chave e janela configurável.
  2. Suportar dimensões: user, API key, tenant, IP, rota, método.
  3. Retornar decisão ALLOW/DENY com motivo.
  4. Expor remaining, reset e retry_after.
  5. Suportar burst + limite sustentado.
  6. Suportar quotas hierárquicas.
  7. Atualizar políticas sem restart global.
  8. Gerar logs de decisão para analytics e forense.

Requisitos Não Funcionais

RequisitoMetaMotivo
Latência de decisão< 5ms p99 no gatewaylimiter não pode virar gargalo
Disponibilidade99,99%camada de proteção crítica
Throughputmilhões de checks/spraticamente todo request passa por aqui
Correçãoerro bounded em distribuiçãofairness e confiança de billing
Propagação de policy< 30sresposta operacional rápida
Isolamentotenants ruidosos contidosproteger plataforma compartilhada

Perguntas de Clarificação

  1. Consistência global estrita é obrigatória?
  2. Quota impacta billing hard?
  3. Edge-only ou também service-to-service?
  4. Qual taxa tolerável de falso bloqueio?
  5. Em falha, fail-open ou fail-closed?

Premissas:

  • enforcement no API gateway,
  • SaaS multi-tenant,
  • deploy multi-região,
  • limites hard para billing,
  • limites soft para cenários de risco baixo.

Cálculos de Envelope

Escala Assumida

Requests/dia: 90 bilhões
RPS médio: ~1.041.667
RPS pico: 6.000.000
Chaves ativas/dia: 80 milhões
Policies ativas: 300 mil

Throughput de Decisão

Checks/s médio ~= 1,04M
Checks/s pico  ~= 6M

Check envolve:

  • parse de dimensões,
  • lookup de policy,
  • operação atômica de contador,
  • retorno de cabeçalhos.

Estado Quente

Se cada estado de contador ativo for ~120 bytes:

80M * 120B ~= 9,6GB estado quente mínimo

Na prática, multiplica por réplicas, dimensões e janelas.

Logging

Se logar 10% das decisões (180B cada):

90B * 0,1 * 180B ~= 1,62TB/dia

Insight

O desafio central é latência baixa + consistência suficiente + comportamento previsível em falhas.


Arquitetura de Alto Nível

flowchart TB
    subgraph Clientes
        APP["Apps/SDKs"]
        INT["Integrações Externas"]
    end

    subgraph Edge
        CDN["CDN"]
        WAF["WAF/Bot Filter"]
        GATE["API Gateway"]
        LOCAL["Local Limiter Cache"]
    end

    subgraph Control Plane
        POLICY["Policy Service"]
        ADMIN["Admin API"]
        DIST["Policy Distribution"]
    end

    subgraph Data Plane
        DECIDE["Decision Service"]
        COUNTER["Counter Store"]
        RISK["Risk Service"]
    end

    subgraph Analytics
        BUS[("Kafka")]
        OLAP[("Warehouse")]
        ALERT["Alerting"]
    end

    APP --> CDN --> WAF --> GATE
    INT --> CDN

    GATE --> LOCAL
    GATE --> DECIDE

    POLICY --> DIST
    DIST --> GATE
    DIST --> DECIDE

    DECIDE --> COUNTER
    DECIDE --> RISK

    GATE --> BUS
    DECIDE --> BUS
    BUS --> OLAP
    BUS --> ALERT

    ADMIN --> POLICY

Princípios

  1. Fast-path local no gateway.
  2. Counter store distribuído para rigor.
  3. Control plane separado do data plane.
  4. Fail mode por criticidade de endpoint.

Escolha de Algoritmos

Fixed Window

  • simples e barato,
  • problema de burst na borda da janela.

Sliding Log

  • precisão alta,
  • custo alto de memória/CPU.

Sliding Window Counter

  • equilíbrio bom,
  • comum em produção.

Token Bucket

  • excelente para burst controlado,
  • muito usado em API gateways.

Leaky Bucket

  • suaviza saída,
  • bom para proteger downstream.

Recomendação Prática

  • token bucket para shaping por cliente,
  • sliding window para quotas de plano,
  • composição hierárquica de algoritmos.
AlgoritmoPrecisãoCustoBurst
Fixedmédia-baixabaixofraco
Sliding Logaltaaltomédio
Sliding Counteraltamédiomédio
Token Bucketaltabaixo-médioforte
Leaky Bucketmédiamédiocontrolado

Contrato de API de Decisão

POST /internal/v1/limit/check

Request:

{
  "request_id": "req_901",
  "subject": {
    "tenant_id": "t_44",
    "api_key_id": "k_77",
    "user_id": "u_12",
    "ip": "203.0.113.8"
  },
  "resource": {
    "route": "/v1/payments",
    "method": "POST",
    "service": "payments-api"
  },
  "context": {
    "region": "us-east-1",
    "risk_score": 0.14
  }
}

Response allow:

{
  "decision": "ALLOW",
  "applied_policy_id": "policy_payments_post_tier2",
  "remaining": 127,
  "reset_after_ms": 1820,
  "retry_after_ms": 0,
  "reason": "WITHIN_LIMIT",
  "limit_headers": {
    "x-ratelimit-limit": "200",
    "x-ratelimit-remaining": "127",
    "x-ratelimit-reset": "2"
  }
}

Response deny:

{
  "decision": "DENY",
  "applied_policy_id": "policy_payments_post_tier2",
  "remaining": 0,
  "reset_after_ms": 780,
  "retry_after_ms": 780,
  "reason": "TOKEN_BUCKET_EMPTY"
}

Modelagem de Dados e Chaves

Padrão de Chave de Contador

rl:{policy_id}:{tenant_id}:{api_key_id}:{route_hash}:{window_bucket}

Exemplo de Policy

{
  "policy_id": "policy_payments_post_tier2",
  "scope": {
    "tenant_tier": "PRO",
    "route": "/v1/payments",
    "method": "POST"
  },
  "algorithm": "TOKEN_BUCKET",
  "config": {
    "capacity": 200,
    "refill_per_sec": 50
  },
  "mode": "HARD",
  "fail_behavior": "FAIL_CLOSED",
  "priority": 900,
  "enabled": true,
  "updated_at": "2026-02-22T22:10:00Z"
}

Quotas Hierárquicas

{
  "quota_tree": [
    { "level": "TENANT", "limit": "50000/min" },
    { "level": "API_KEY", "limit": "1000/min" },
    { "level": "ROUTE", "limit": "200/min" }
  ]
}

Boas Práticas

  1. TTL para buckets.
  2. Policy versionada.
  3. Separar hot counters de histórico analítico.

Limiting Embutido no Gateway (Core 1)

Vantagens

  1. menos hop de rede,
  2. bloqueio antecipado,
  3. melhor custo por decisão.

Fluxo Híbrido

sequenceDiagram
    participant C as Cliente
    participant G as Gateway
    participant L as Local Limiter
    participant R as Remote Limiter

    C->>G: request
    G->>L: local check

    alt local deny
        L-->>G: deny
        G-->>C: 429
    else local allow
        L-->>G: provisional allow
        G->>R: strict/global check (if needed)
        alt remote deny
            R-->>G: deny
            G-->>C: 429
        else allow
            R-->>G: allow
            G-->>C: forward upstream
        end
    end

Trade-off

Só local = rápido, menos preciso globalmente.

Híbrido = bom equilíbrio.


Serviço Distribuído de Decisão (Core 2)

Responsabilidades

  1. resolver policy,
  2. atualizar contador atômico,
  3. retornar decisão,
  4. emitir evento de auditoria.

Atomicidade

Use script atômico (ex: Lua em Redis) para check + decrement.

Sem atomicidade, concorrência cria allow indevido.

Particionamento

Shard por hash(policy + subject).

Multi-DC

Global estrito em todo request costuma estourar latência. Para muitos cenários, bounded inconsistency com controle é melhor.


Quotas Globais e Regionais (Core 3)

Problema

Tenant global com limite diário, tráfego distribuído em várias regiões.

Opção Prática: Budget Leasing

  • gerenciador global entrega "lotes de quota" para regiões,
  • região consume localmente com baixa latência,
  • solicita novo lote quando perto do fim.
flowchart LR
    GQ["Global Quota Manager"] --> R1["Region A Lease"]
    GQ --> R2["Region B Lease"]
    GQ --> R3["Region C Lease"]

    R1 --> C1["Local Counter"]
    R2 --> C2["Local Counter"]
    R3 --> C3["Local Counter"]

Trade-offs

  • pequena discrepância temporal,
  • grande ganho de latência/disponibilidade.

Burst e Suavização (Core 4)

Regra Composta

Combinar:

  1. limite de burst curto,
  2. limite sustentado longo.
ALLOW se burst_ok && sustained_ok

Retry-After com Jitter

Retornar retry com jitter ajuda a evitar retry storm sincronizado.


Políticas por Plano e Tenant (Core 5)

Exemplo de Plano

PlanoLimite GlobalBurst
Free60/min10/5s
Pro3.000/min200/5s
Enterprisecustomcustom

Ordem de Resolução

  1. bloqueio emergencial,
  2. override de tenant,
  3. default de plano,
  4. ajuste por rota,
  5. fallback anônimo.

Requisito

Mudança de policy sem redeploy em massa.


Limites Adaptativos por Risco (Core 6)

Inputs

  1. risco comportamental,
  2. taxa de falha de auth,
  3. detecção de anomalia,
  4. sensibilidade da rota,
  5. status de incidente regional.

Exemplo

if risk_score > 0.9 -> reduzir limite 80%
if 0.7 <= risk_score <= 0.9 -> reduzir 40%
else -> limite padrão

Guardrails

  • limite máximo de ajuste,
  • decaimento temporal,
  • whitelist controlada para integrações críticas.

Idempotência e Retries (Core 7)

Questão

Retry de request idempotente deve consumir quota novamente?

Modelos

  1. cobrar tentativa (mais simples, mais duro),
  2. cobrar chave idempotente única (mais justo em rede instável).

Recomendação

  • endpoints financeiros: considerar dedupe por idempotency-key,
  • endpoints de risco/abuso: cobrar tentativa.

Chave de Dedupe

(api_key, idempotency_key, route)

Resistência a Abuso e Evasão (Core 8)

Táticas de Evasão

  1. rotação de IP,
  2. troca de API keys,
  3. low-and-slow distribuído,
  4. user-agent aleatório.

Defesa em Camadas

  1. chave multidimensional,
  2. WAF antes do limiter,
  3. score de comportamento,
  4. challenge progressivo,
  5. sinais de honeypot.

Regra Prática

DENY se qualquer dimensão hard estourar
THROTTLE para risco moderado
ALLOW com observabilidade para tráfego normal

Caching e Estratégia de Storage

Split de Dados

  1. counters quentes em in-memory,
  2. policies em config store durável,
  3. logs em stream + warehouse.

Caches

  • local policy cache,
  • negative cache curto para blocos recentes,
  • cache de decisão repetida em janelas curtíssimas.

TTLs

  • bucket TTL alinhado com janela,
  • deny cache curto,
  • policy cache com invalidação por versão.

Confiabilidade e Degradação

Falhas

  1. counter store fora,
  2. policy stale,
  3. partição inter-região,
  4. skew de clock.

Matrix de Fail Mode

Tipo de endpointComportamento
pagamento/críticofail-closed ou fallback estrito
leitura geralfail-open com caps emergenciais
interno baixo riscofail-open com telemetria

Plano de Degradação

  1. ativar limites estáticos locais,
  2. apertar dimensões de alto risco,
  3. desligar lógica adaptativa custosa,
  4. preservar disponibilidade core.

Observabilidade e SLOs

SLOs

SLISLO
latência de decisão p99< 5ms
disponibilidade> 99,99%
lag de propagação de policy p95< 30s
falso bloqueio em coorte válidaabaixo da meta
erro do counter storedentro do error budget

Golden Signals

  1. allow/deny por rota/tenant,
  2. latência de decisão,
  3. tempo de comando no counter store,
  4. skew de versão de policy,
  5. fail-open activation.

Trace

x-request-id
x-tenant-id
x-api-key-id
x-policy-id
x-rate-limit-decision

Dicas de Entrevista

Estrutura

  1. Clarifique dimensões e rigidez.
  2. Justifique algoritmo.
  3. Desenhe gateway + serviço distribuído.
  4. Explique quotas globais por lease.
  5. Trate fail mode por criticidade.
  6. Feche com observabilidade e abuse.

Erros Comuns

  1. contador global único para tudo,
  2. policy hardcoded,
  3. sem idempotência,
  4. sem plano de degradação,
  5. sem estratégia anti-evasão.

Script Curto

  1. fast check local,
  2. strict check remoto quando necessário,
  3. limites hierárquicos,
  4. lease regional para quota global,
  5. fail-open/closed por endpoint.

Anti-Patterns

1) Limitar só por IP

Problema: evasão fácil e falso bloqueio por NAT.

Correção: chaves multidimensionais.

2) Limites hardcoded no código

Problema: resposta lenta a incidentes.

Correção: policy service versionado.

3) Check/decrement não atômico

Problema: race condition em alta concorrência.

Correção: operação atômica.

4) Consistência global estrita para tudo

Problema: latência/availability ruins.

Correção: consistência pragmática por risco.

5) Fail-open sempre

Problema: abuso passa livre em falha.

Correção: matrix de fail behavior.

6) Sem headers de limite

Problema: cliente não sabe quando retryar.

Correção: Retry-After e headers padrão.

7) Sem monitorar skew de policy

Problema: comportamento inconsistente por região.

Correção: monitoramento e alerta de convergência.


Conclusão

Rate limiter de produção é uma camada distribuída de controle de risco e capacidade.

Arquitetura madura combina:

  1. decisão rápida na borda,
  2. estado distribuído com atomicidade,
  3. políticas flexíveis por plano,
  4. adaptação por risco,
  5. degradação previsível,
  6. observabilidade forte.

Esse é um dos temas mais recorrentes em entrevistas porque separa respostas superficiais de engenharia realmente pragmática.


Referências


Referência Rápida

Componentes

ComponenteResponsabilidade
API Gatewayenforcement inicial
Local Limiter Cachecheck ultrarrápido
Decision Servicedecisão estrita distribuída
Counter Storeestado atômico de bucket
Policy Servicedefinição e distribuição
Risk Serviceajuste adaptativo
Analytics Pipelinevisibilidade e tuning

Regras Críticas

  1. Separar control plane de data plane.
  2. Aplicar limites hierárquicos.
  3. Garantir atomicidade no contador.
  4. Definir fail mode por endpoint.
  5. Medir falso bloqueio e drift de policy.

Resumo de 10 minutos

1) Dimensões + criticidade.
2) Token bucket + sliding window.
3) Fast local + strict remoto.
4) Quota global por lease regional.
5) Observabilidade + abuse controls + degradação.

Você agora tem um blueprint completo para rate limiting distribuído em escala global.

Carregando publicação patrocinada...