Rate Limiting (Limitação de Frequência de Requisições e Proteção de API)
Mecanismo sistêmico de controle da intensidade do tráfego de entrada e saída (Token Bucket, Sliding Window) para proteger o backend contra esgotamento de recursos, ataques de força bruta, DDoS na camada 7 e estouro financeiro em endpoints de IA.
1. Visão geral da concepção e problema sistêmico
Sem um mecanismo robusto de limitação de taxa (rate limiting), qualquer serviço web aberto ou endpoint de API está sob ameaça constante de colapso técnico ou financeiro:
- Esgotamento financeiro (AI Billing Drain): Um atacante ou script em loop pode enviar 100.000 requisições à sua rota de geração de código ou imagens em apenas 5 minutos, gerando uma fatura de $5.000 na OpenAI ou Anthropic.
- Brute Force e Credential Stuffing: Botnets automatizados testam milhões de senhas no formulário de login
/api/auth/login, sobrecarregando o banco de dados com operações pesadas de hashing bcrypt/Argon2. - Falha em cascata do banco de dados (Denial of Service): Chamadas paralelas massivas a endpoints de busca não cacheados esgotam o pool de conexões do PostgreSQL, paralisando toda a aplicação.
Rate Limiting é o escudo fundamental da segurança sistêmica. Ele mede a intensidade do tráfego por identificador (IP, ID de sessão, chave de API) e corta o tráfego excedente nos estágios iniciais do pipeline, garantindo previsibilidade de carga e continuidade do serviço para usuários legítimos.
2. Taxonomia arquitetural e modelo mental
Escolha arquitetural de algoritmos e níveis de implementação da limitação de tráfego:
┌─────────────────────────────────────────────────────────────┐
│ TAXONOMIA ALGORÍTMICA DE RATE LIMITING │
├─────────────────────────────────────────────────────────────┤
│ 1. Janela Fixa: Contador simples com reset a cada minuto │
│ (Vulnerável a picos de tráfego 2x na borda do intervalo) │
├─────────────────────────────────────────────────────────────┤
│ 2. Contador de Janela Deslizante: Janela deslizante híbrida │
│ Peso = Contagem_Anterior * (1 - Proporção_Elapsed) + │
│ Contagem_Atual │
│ (Compromisso ideal: precisão + consumo mínimo de RAM) │
├─────────────────────────────────────────────────────────────┤
│ 3. Balde de Tokens: Reposição de tokens a uma taxa constante│
│ (Permite picos legítimos de tráfego até a capacidade do │
│ balde) │
├─────────────────────────────────────────────────────────────┤
│ 4. Balde Vazante: Taxa constante de vazamento da fila │
│ (Ideal para suavizar as requisições de saída para APIs) │
└─────────────────────────────────────────────────────────────┘
- Janela deslizante híbrida (Sliding Window Counter):
- Mantém contadores para os intervalos de tempo atual e anterior. A cada requisição, calcula uma soma ponderada baseada na porcentagem de tempo decorrido na janela atual. Elimina anomalias nas bordas dos minutos.
- Hierarquia de identificação do cliente (Subject Identification):
- Nível público: IP (para requisições anônimas e proteção contra DDoS).
- Nível autenticado:
User_IDouOrganization_ID(ignora redes corporativas compartilhadas NAT/VPN). - Nível de token: Cotas granulares por tipo de plano contratado (Free, Pro, Enterprise).
- Backend distribuído de armazenamento de estado (Redis Cluster / Upstash):
- Armazenamento centralizado em memória (In-Memory) que sincroniza contadores entre dezenas de instâncias do backend em microssegundos.
3. Pipeline técnico e mecânica interna
Ciclo de vida da verificação de requisição via Redis com script Lua atômico:
- Extração do identificador e da rota:
O Middleware intercepta a requisição entrante. É formada uma chave combinada:
rate:auth:${req.ip}para o formulário de login ourate:llm:${user.id}para a rota de AI. - Execução atômica do script Lua no Redis:
Para evitar condições de corrida (Race Condition) entre requisições paralelas, toda a lógica é encapsulada em um único script Lua:
- Lê-se o timestamp atual.
- Removem-se registros mais antigos que o tamanho da janela deslizante (60 segundos).
- Calcula-se o número de tokens ativos.
- Tomada de decisão:
- Se o limite não for excedido: O contador é incrementado em 1 (ou pelo custo da requisição em tokens), define-se o TTL da chave e a requisição é passada adiante ao controller.
- Se o limite for excedido: Gera-se uma resposta de recusa.
- Formatação dos cabeçalhos HTTP padrão:
O servidor retorna metadados ao cliente:
HTTP/1.1 429 Too Many Requests Content-Type: application/json Retry-After: 24 X-RateLimit-Limit: 10 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1718293840 - Telemetria e alertas: O evento de estouro do limite é registrado no sistema de monitoramento; em caso de pico anômalo vindo de uma sub-rede, dispara-se uma regra de bloqueio no firewall.
4. Cenários práticos de engenharia em produção
01. Proteção de rotas caras de AI generativa (Token-Aware Limiting)
A rota de geração de código consome tokens proporcionalmente à complexidade da requisição:
- Em vez de contar simples requisições, o rate limiter debita do saldo virtual do usuário a quantidade exata de tokens gerados.
- Usuários do plano gratuito têm um limite de 50.000 tokens por dia. Ao esgotar o limite, a API bloqueia a geração até o início do próximo dia.
02. Proteção do formulário de autenticação contra brute force (Credential Defense)
Endpoint /api/auth/sign-in:
- São permitidas no máximo 5 tentativas falhas de senha em 15 minutos para uma combinação IP + Email.
- Na 6ª tentativa, o sistema exige a resolução de um captcha ou envia um link de redefinição de senha por e-mail, neutralizando completamente tentativas de ataque por dicionário.
03. Suavização do tráfego de saída para gateways de pagamento externos
Integração com Stripe, onde há um limite de 100 requisições por segundo:
- O microsserviço interno utiliza uma fila com o algoritmo Leaky Bucket.
- Mesmo que agentes internos da empresa criem simultaneamente 500 pagamentos durante a Black Friday, a fila envia as requisições em um fluxo estritamente uniforme (80 req/s), eliminando o risco de bloqueio da conta Stripe.
5. Armadilhas, erros comuns e segurança
- Bloqueio de escritórios inteiros por Rate Limiting ingênuo por IP: Se aplicar um limite rigoroso puramente por IP a usuários autorizados, um funcionário ativo em um centro comercial bloqueará todos os colegas que acessam a internet através do endereço NAT compartilhado da empresa. Após o login, sempre limite por
user_id. - Race Condition ao usar operações separadas
GETeINCR: Se verificar o limite comGETe depois incrementá-lo comINCR, um atacante pode enviar 100 requisições assíncronas simultâneas, e todas passarão pela verificação antes que o contador seja atualizado. Use scripts atômicos. - Estouro de memória do Redis ao armazenar timestamps: O uso de listas não ordenadas para armazenar o timestamp de cada requisição sem definir um TTL rígido rapidamente preenche gigabytes de RAM durante ataques massivos.
- Ignorar cabeçalhos de proxy (
X-Forwarded-ForSpoofing): Se seu servidor estiver atrás do Cloudflare ou Nginx e você ler o IP diretamente do socket, obterá o endereço local do proxy. Por outro lado, confiar cegamente no cabeçalho não validadoX-Forwarded-Forpermite que um atacante falsifique qualquer endereço IP.
FAQ: Rate Limiting (Limitação de Frequência de Requisições e Proteção de API)
Termos relacionados
Higiene de Segredos e .env (Secret Hygiene & Git Safety)
Conjunto de práticas de engenharia, cofres criptográficos e scanners pre-commit (Gitleaks, Doppler, Infisical) para gestão segura de chaves de API, tokens e senhas sem risco de vazamento para o espaço público.
UFW & Fail2ban (Proteção de Rede e Bloqueio de Ataques)
Tandem sistêmico da utilidade de filtragem de pacotes UFW (Uncomplicated Firewall) e do daemon Fail2ban, que analisa logs do sistema em tempo real e bloqueia dinamicamente endereços IP de atacantes.
Proxy reverso (Nginx, Caddy, Traefik)
Camada de arquitetura de servidor intermediária que recebe tráfego externo da internet (portas 80/443), realiza a terminação SSL/TLS, compressão (Brotli/Gzip), cache de arquivos estáticos e roteia com segurança as requisições para aplicações internas.
OpenRouter (Gateway Unificado de Modelos)
Um gateway unificado de inteligência artificial que oferece acesso padronizado a centenas de modelos de linguagem, tanto fechados quanto abertos, provenientes de dezenas de provedores de inferência, através de um único saldo, uma única chave de API e um mecanismo automático de tolerância a falhas com fallback.