Rate limiting por usuario e uma das medidas mais eficazes para proteger sua API contra abusos, ataques de forca bruta e uso excessivo de recursos. Neste guia, voce aprendera a implementar essa protecao passo a passo, desde a escolha do algoritmo ate a configuracao final no servidor. Ao final, sua aplicacao estara mais segura e seus recursos, melhor distribuidos.
Pre-requisitos
Antes de comecar, tenha em maos: um servidor ou ambiente de desenvolvimento com acesso a um banco de dados ou cache (como Redis ou Memcached), conhecimento basico de middleware em sua linguagem de preferencia, e acesso ao codigo-fonte da aplicacao que deseja proteger. Nao e necessario um sistema em producao, um ambiente de testes ja basta para os primeiros passos.
Passo 1: Identifique o usuario em cada requisicao
O primeiro passo e definir como voce vai identificar cada usuario. O identificador precisa ser unico e presente em toda requisicao autenticada. As opcoes mais comuns sao o ID do usuario (extraido do token JWT ou sessao), o endereco IP (para requisicoes nao autenticadas) ou uma chave de API.
Dica: prefira o ID do usuario sempre que possivel. O IP pode ser compartilhado por varios usuarios em uma mesma rede corporativa ou via NAT, o que geraria bloqueios indevidos. Um erro comum e usar apenas o IP em aplicacoes com autenticacao, penalizando usuarios legitimos.
Passo 2: Escolha o algoritmo de rate limiting
Existem tres algoritmos principais para implementar rate limiting. Cada um tem vantagens e desvantagens que influenciam o comportamento do sistema.
Token Bucket
Funciona como um balde que e preenchido com tokens a uma taxa constante. Cada requisicao consome um token. Se o balde estiver vazio, a requisicao e negada. E simples de implementar e permite picos curtos de trafego.
Sliding Window Log
Mantem um registro dos timestamps de cada requisicao do usuario. Quando uma nova requisicao chega, o sistema conta quantas requisicoes ocorreram dentro da janela de tempo atual. E mais preciso, mas consome mais memoria.
Fixed Window
Divide o tempo em janelas fixas (ex.: 1 minuto) e conta as requisicoes dentro de cada janela. E o mais simples, mas pode permitir o dobro do limite no limite entre duas janelas.
Erro comum: implementar Fixed Window sem considerar o efeito de borda. Um usuario pode fazer 100 requisicoes no final de um minuto e mais 100 no inicio do seguinte, totalizando 200 em menos de 2 segundos. Token Bucket ou Sliding Window evitam esse problema.
Passo 3: Defina os limites por usuario
Os limites dependem do perfil de uso da sua aplicacao. Nao existe um valor universal. Para uma API publica, 100 requisicoes por minuto por usuario e um ponto de partida comum. Para uma API interna, 1000 requisicoes por minuto podem ser aceitaveis.
Considere criar diferentes niveis de limite: um para usuarios gratuitos, outro para premium, e um terceiro para requisicoes nao autenticadas (mais restritivo). Documente esses limites em sua documentacao da API.
Dica: monitore o trafego real por pelo menos uma semana antes de definir limites definitivos. Use ferramentas como logs do servidor ou APM para identificar o percentil 95 de uso.
Passo 4: Implemente o middleware de rate limiting
O middleware e o componente que intercepta cada requisicao antes dela chegar ao controller. Nele, voce aplica a logica de verificacao e incremento do contador.
Em Node.js com Express, um exemplo simples com Redis e Token Bucket seria:
const redis = require('redis'); const client = redis.createClient();
async function rateLimit(req, res, next) { const userId = req.user.id; const key = rate_limit:${userId}; const maxTokens = 100; const refillRate = 10; // tokens por segundo
// Logica para obter tokens atuais e refill const currentTokens = await client.get(key); if (currentTokens === null) { await client.set(key, maxTokens - 1, 'EX', 60); return next(); }
if (parseInt(currentTokens) <= 0) { return res.status(429).json({ error: 'Muitas requisicoes. Tente novamente mais tarde.' }); }
await client.decr(key); next(); }
Erro comum: nao definir um tempo de expiracao (TTL) para a chave no Redis. Sem TTL, chaves de usuarios inativos acumulam-se e consomem memoria desnecessariamente.
Passo 5: Configure os headers de resposta
Headers HTTP informam o cliente sobre o estado do rate limiting. Os tres headers padrao sao:
X-RateLimit-Limit: o numero maximo de requisicoes permitidas no intervalo.X-RateLimit-Remaining: quantas requisicoes ainda podem ser feitas.X-RateLimit-Reset: timestamp Unix de quando o limite sera reiniciado.
Incluir esses headers permite que o cliente se adapte ao limite sem precisar esperar um erro 429. Aplicativos bem comportados podem diminuir a taxa de requisicoes ao se aproximar do limite.
Dica: o header Retry-After no corpo da resposta 429 e util para informar, em segundos, quando o cliente pode tentar novamente. Isso reduz a carga no servidor e melhora a experiencia do usuario.
Passo 6: Trate o erro 429 corretamente
Quando o limite e excedido, a resposta deve ser clara e util. Use o codigo HTTP 429 (Too Many Requests) com um corpo JSON explicativo. Evite respostas genericas como "erro interno".
Um exemplo de resposta:
{ "error": "limite_de_requisicoes_excedido", "message": "Voce excedeu o limite de 100 requisicoes por minuto. Tente novamente em 45 segundos.", "retry_after": 45 }
Erro comum: retornar 429 sem informacao sobre quando o limite sera reiniciado. O cliente fica sem saber se deve tentar em 5 segundos ou 5 minutos.
Passo 7: Teste e monitore a implementacao
Antes de colocar em producao, teste o rate limiting com ferramentas como Apache Bench, wrk ou scripts personalizados. Simule cenarios de abuso e verifique se o bloqueio ocorre no limite correto.
Monitore metricas como: numero de requisicoes bloqueadas por usuario, falsos positivos (usuarios bloqueados sem motivo), e latencia adicionada pelo middleware. Se a latencia aumentar mais de 5ms, considere otimizar a consulta ao cache.
Dica: implemente um modo de auditoria inicial, onde o rate limiting e calculado mas nao aplicado. Isso permite coletar dados sem impactar usuarios reais, ajudando a ajustar os limites antes da ativacao.
Checklist do que foi implementado
- [ ] Identificador unico de usuario extraido em cada requisicao
- [ ] Algoritmo de rate limiting escolhido (Token Bucket, Sliding Window ou Fixed Window)
- [ ] Limites definidos por perfil de usuario (gratuito, premium, anonimo)
- [ ] Middleware implementado e acoplado as rotas protegidas
- [ ] Headers de resposta configurados (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset)
- [ ] Tratamento de erro 429 com mensagem clara e Retry-After
- [ ] Testes realizados com ferramentas de carga
- [ ] Monitoramento de metricas ativo
Perguntas frequentes sobre rate limiting por usuario
Qual a diferenca entre rate limiting e throttling?
Rate limiting bloqueia requisicoes que excedem um limite pre-definido. Throttling, por outro lado, atrasa as requisicoes em vez de bloquea-las, permitindo que o usuario continue usando o servico, mas em ritmo mais lento. Rate limiting e mais comum em APIs para evitar abusos.
O que acontece se o Redis cair durante o rate limiting?
Se o Redis ficar indisponivel, suas requisicoes podem falhar ou o rate limiting pode ser desabilitado. Uma boa pratica e implementar um fallback: em caso de erro de conexao com o Redis, permita a requisicao (fail-open) para nao bloquear usuarios, mas registre o incidente para alerta.
Rate limiting por usuario funciona para APIs publicas sem autenticacao?
Sim, mas o identificador passa a ser o endereco IP. Como IPs podem ser compartilhados, o limite deve ser mais generoso (ex.: 1000 requisicoes por minuto por IP) e combinado com outras tecnicas como CAPTCHA para evitar abusos.
Como definir o limite ideal para minha aplicacao?
Nao existe limite universal. Analise os logs de trafego por duas semanas, identifique o percentil 95 de uso por usuario, e defina o limite 20% acima desse valor. Monitore e ajuste conforme necessario.
E possivel ter rate limiting sem usar Redis?
Sim. Voce pode usar o banco de dados principal (PostgreSQL, MySQL) ou ate mesmo a memoria da aplicacao. Porem, o banco de dados pode se tornar um gargalo sob alta carga, e a memoria e perdida ao reiniciar o servidor. Redis e a escolha mais comum por ser rapido e persistente.
Devo aplicar rate limiting em todas as rotas?
Nem todas. Rotas estaticas (arquivos CSS, imagens) geralmente nao precisam. Priorize rotas de API que consomem mais recursos ou sao alvo comum de ataques, como login, cadastro e endpoints de busca. Rotas de leitura de dados publicos podem ter limites mais generosos.