Rate Limiting: A Primeira Linha de Defesa da Sua API
Sem rate limiting, um único usuário (ou bot) pode sobrecarregar sua API com milhares de requests por segundo. Rate limiting limita o número de requisições que um cliente pode fazer em uma janela de tempo.
Algoritmos Comuns
| Algoritmo | Como Funciona | Prós | Contras |
|---|---|---|---|
| Fixed Window | Conta requests por janela fixa de tempo | Simples | Burst nas bordas da janela |
| Sliding Window | Conta requests em janela deslizante | Distribuição suave | Mais memória |
| Token Bucket | Tokens reabastecem em taxa fixa; cada request custa um token | Permite bursts controlados | Ligeiramente complexo |
Headers de Resposta
HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1682345700
HTTP/1.1 429 Too Many Requests
Retry-After: 30
{ "error": "Rate limit excedido" }Express.js com Redis
import rateLimit from 'express-rate-limit';
import RedisStore from 'rate-limit-redis';
const limiter = rateLimit({
windowMs: 60 * 1000,
max: 100,
standardHeaders: true,
store: new RedisStore({
sendCommand: (...args) => redis.call(...args),
}),
});
app.use('/api/', limiter);
// Limites diferentes por endpoint
const strictLimiter = rateLimit({ windowMs: 60000, max: 10 });
app.post('/api/auth/login', strictLimiter, loginHandler);Sliding Window DIY com Redis
async function checkRateLimit(userId, limit = 100, window = 60) {
const key = `rate:${userId}`;
const now = Date.now();
const windowStart = now - window * 1000;
const pipeline = redis.pipeline();
pipeline.zremrangebyscore(key, 0, windowStart);
pipeline.zadd(key, now, `${now}:${Math.random()}`);
pipeline.zcard(key);
pipeline.expire(key, window);
const results = await pipeline.exec();
const count = results[2][1];
return { allowed: count <= limit, remaining: Math.max(0, limit - count) };
}Boas Práticas
- Retorne status
429com headerRetry-After - Inclua headers de rate limit em toda resposta
- Use limites diferentes por endpoint (login vs leitura)
- Registre rate limit hits para detecção de abuso