O que é rate limiting e por que é essencial
Controlar quantas requisições cada cliente pode fazer por unidade de tempo
Rate limiting é o mecanismo que limita a frequência com que um cliente pode chamar uma API em um intervalo de tempo. Sem rate limiting, um único cliente mal-intencionado, um script com bug em loop ou um bot agressivo pode fazer dezenas de milhares de requisições por segundo e tornar a API inoperante para todos os outros usuários. A proteção não é apenas contra ataques — é também contra clientes legítimos com comportamento incorreto (como retry em loop sem exponential backoff) que inadvertidamente sobrecarregam o sistema. Rate limiting é proteção tanto de disponibilidade quanto de equidade no uso dos recursos.
Algoritmos de rate limiting — como cada um funciona
Token bucket, sliding window, fixed window e leaky bucket
Os quatro algoritmos principais são: Fixed Window (conta requisições em janelas fixas de tempo — simples mas vulnerável a burst no limite da janela), Sliding Window (conta requisições nos últimos N segundos de forma contínua — mais preciso, mais custoso), Token Bucket (cada cliente tem um balde de tokens que recarrega a uma taxa fixa; cada requisição consome um token — permite burst controlado), e Leaky Bucket (requisições entram em uma fila e são processadas em taxa constante — garante taxa uniforme mas pode atrasar). Token bucket com sliding window é o mais usado em produção por equilibrar precisão com capacidade de burst para clientes legítimos.
Granularidade — por onde limitar
IP, usuário autenticado, API key, rota, serviço de origem
A granularidade do rate limit define quem compartilha o mesmo limite. Limitar por IP protege contra ataques externos mas pode bloquear usuários legítimos atrás de NAT compartilhado (como empresas onde todos compartilham o mesmo IP). Limitar por usuário autenticado é mais preciso para APIs com autenticação. Por API key é ideal para B2B onde cada cliente tem sua chave. Por rota permite limites diferentes para operações caras versus baratas (POST com processamento pesado tem limite menor que GET de listagem). Em produção, geralmente se combina múltiplas granularidades: global por IP para proteção básica e por usuário autenticado para controle granular.
Rate limiting distribuído com Redis
Como compartilhar contadores entre múltiplas instâncias da aplicação
Em aplicações com múltiplas instâncias, cada servidor não pode manter contadores locais — um cliente poderia fazer 100 requisições para cada instância, burlando um limite de 100 por minuto. A solução padrão é Redis como contador distribuído. O algoritmo de fixed window com Redis usa INCR e EXPIRE: INCR key incrementa o contador atomicamente e EXPIRE define a janela de tempo. Para sliding window mais preciso, Redis Sorted Sets armazenam o timestamp de cada requisição, e a contagem remove timestamps fora da janela. Bibliotecas como rate-limiter-flexible (Node.js) e AspNetCoreRateLimit (.NET) abstraem esse Redis storage.
Headers de rate limit — comunicando os limites ao cliente
RateLimit-Limit, RateLimit-Remaining e RateLimit-Reset
Clientes que consomem APIs precisam saber quando retryar e quanto do limite está disponível. Os headers padronizados (RFC 6585 e draft IETF) são: X-RateLimit-Limit (limite máximo do período), X-RateLimit-Remaining (requisições restantes na janela atual), e X-RateLimit-Reset (timestamp UNIX de quando o limite será reiniciado). O status HTTP correto para requisições rejeitadas por rate limit é 429 (Too Many Requests) com o header Retry-After indicando em quantos segundos o cliente pode tentar novamente. APIs que retornam 429 com Retry-After correto reduzem drasticamente o número de retries agressivos que pioram a situação.
Estratégias de resposta para requisições bloqueadas
Rejeitar, enfileirar ou degradar gracefully
Quando um cliente ultrapassa o limite, há três abordagens: rejeitar imediatamente com 429 (mais simples, protege o servidor mas pode causar erros visíveis ao usuário), enfileirar a requisição para processamento quando o limite liberar (melhor UX mas aumenta memória e latência), e degradar gracefully com resposta parcial ou cacheada (retornar dado mais antigo ou resultado de qualidade reduzida em vez de erro). Para APIs públicas, rejeitar com 429 e Retry-After é o padrão. Para interfaces de usuário interno, degradação graceful com dados em cache é melhor experiência. Para jobs em background, enfileirar com backoff é o comportamento mais correto.
Rate limiting por serviço — proteção em microsserviços
Cada microsserviço deve ter seus próprios limites configurados
Em arquitetura de microsserviços, rate limiting deve existir em múltiplas camadas: no API Gateway (limite por cliente externo antes de chegar aos serviços internos), em cada microsserviço (limite por serviço chamador para evitar que um serviço sobrecarregue outro), e no cliente HTTP de cada serviço (circuit breaker + rate limiting para chamadas a serviços externos como APIs de terceiros). Ferramentas como Kong, AWS API Gateway, NGINX e Envoy Proxy têm rate limiting nativo. Para microsserviços internos, o padrão é implementar no próprio serviço usando Redis compartilhado para contadores distribuídos.
Diferença entre rate limiting e throttling
Termos parecidos com comportamentos distintos
Rate limiting rejeita requisições que excedem o limite — o cliente recebe erro imediato. Throttling desacelera o processamento — o servidor aceita a requisição mas a enfileira ou atrasa a resposta para processar em taxa controlada. Na prática, rate limiting é hard limit (rejeição) e throttling é soft limit (desaceleração). APIs públicas geralmente usam rate limiting para proteger recursos e oferecer planos com limites diferentes (free: 100/hora, paid: 10000/hora). Sistemas internos com SLAs mais flexíveis podem preferir throttling para absorver picos sem rejeitar requisições de serviços próprios.
Evitando falsos positivos — limites que bloqueiam usuários legítimos
Rate limits muito apertados são tão ruins quanto não ter rate limit
Um rate limit mal calibrado bloqueia usuários legítimos e gera suporte desnecessário. Para calibrar corretamente: analise o padrão real de uso antes de definir limites (percentil 99 de requisições por usuário em um dia normal é o piso mínimo do limite), use limites por nível de usuário (usuário gratuito vs premium vs enterprise), implemente whitelist para IPs confiáveis de parceiros e sistemas internos, e monitore a taxa de 429 para detectar falsos positivos. Um limite que gera mais de 0.1% de 429 em tráfego legítimo provavelmente está muito restrito.
Conclusão — rate limiting é proteção e qualidade de serviço
Limites bem definidos protegem todos os usuários igualmente
Rate limiting não é apenas proteção contra abuso — é garantia de qualidade de serviço igual para todos os clientes. Sem ele, um cliente agressivo consome recursos que prejudicam todos os outros. Com rate limits bem calibrados, a API mantém performance previsível mesmo sob pressão, clientes são incentivados a usar de forma eficiente, e o sistema tem uma primeira linha de defesa contra ataques de DDoS em nível de aplicação. Implemente antes do lançamento público — adicionar rate limiting após usuários estarem acostumados com comportamento irrestrito é muito mais difícil. Continue em: Fundamentos obrigatórios antes de produção.
Rate Limiting e Proteção de APIs — Vídeos
Good API Design, Bad API Design + API Rate Limiting — CodeOpinion
What Is JWT and Why Should You Use It — Web Dev Simplified
What is a Race Condition? — Nutshell
How does the Internet work? — freeCodeCamp
The Complexity Iceberg — fundamentos de sistemas distribuídos
Master Software Architecture — GOTO 2025
Rate Limiting e Segurança de APIs no Instagram
Token Bucket
Algoritmo de rate limiting com balde de tokens que recarrega em taxa fixa — permite burst controlado para picos legítimos.
Sliding Window
Conta requisições nos últimos N segundos de forma contínua — mais preciso que fixed window.
429 Too Many Requests
Status HTTP correto para requisições rejeitadas por rate limit — deve incluir Retry-After.
RateLimit-Remaining
Header HTTP que indica quantas requisições ainda podem ser feitas na janela atual.
Retry-After
Header HTTP que indica em quantos segundos o cliente pode tentar novamente após receber 429.
Throttling
Desacelera o processamento em vez de rejeitar — soft limit que enfileira em vez de retornar erro.
Rate Limiting no X
@bytebytego
Reels — Sistemas e Arquitetura
@bytebytego
ByteByteGo no Facebook
Referências e Leituras Recomendadas
Como testar que sua API é resiliente e segura para produção real
Ver post completo no X →Implementando padrões de resiliência em .NET Core com exemplos reais
Ver post completo no X →Vertical Slice Architecture — organizando sistemas para escala
Ver post completo no X →5 anos com Clean Architecture — lições de sistemas em produção
Ver post completo no X →Design de APIs resilientes — retry, backoff e idempotência juntos
Ver post completo no X →Monolito vs Microsserviços — como escolher para cada contexto
Ver post completo no X →O que dizem