Experto en Limitación de Velocidad y Estrangulamiento de API
Implementa limitación de velocidad justa y eficiente usando los algoritmos de token bucket, ventana deslizante y ventana fija con contadores distribuidos respaldados por Redis.
Disparadores de Activación
Actívalo en: "limitación de velocidad", "estrangulamiento", "token bucket", "ventana deslizante", "abuso de API", "protección DDoS", "gestión de cuotas", "429 Demasiadas Solicitudes", "límites de solicitud"
NO para: Configuración de pasarela API → api-gateway-reverse-proxy-expert | Estrategias de caché → cache-strategy-invalidation-expert | Reglas de WAF/firewall → habilidad de seguridad relevante
Inicio Rápido
- Define límites — solicitudes/minuto por clave de API, IP o nivel de usuario
- Elige algoritmo — registro de ventana deslizante (preciso), token bucket (ráfagas), ventana fija (simple)
- Usa Redis — operaciones atómicas con
MULTI/EXECo scripts Lua para limitación distribuida - Devuelve cabeceras correctas —
X-RateLimit-Limit,X-RateLimit-Remaining,Retry-After - Diferencia niveles — free/pro/enterprise obtienen límites distintos
Capacidades Principales
| Dominio | Tecnologías |
|---|---|
| Algoritmos | Token bucket, registro de ventana deslizante, contador de ventana deslizante, ventana fija |
| Almacenamiento | Redis 7.4+, Valkey, DragonflyDB, en memoria (nodo único) |
| Librerías | rate-limiter-flexible, @upstash/ratelimit, express-rate-limit |
| Plugins de Pasarela | Kong rate-limiting, Nginx limit_req, Traefik ratelimit |
| Estándares | RFC 6585 (429), Cabeceras RateLimit (draft-ietf-httpapi-ratelimit) |
Patrones de Arquitectura
Contador de Ventana Deslizante (Redis Lua)
-- Script Lua de Redis: limitador de ventana deslizante
-- KEYS[1] = clave de límite
-- ARGV[1] = tamaño de ventana (segundos)
-- ARGV[2] = solicitudes máximas
-- ARGV[3] = marca de tiempo actual
local key = KEYS[1]
local window = tonumber(ARGV[1])
local limit = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
-- Eliminar entradas caducadas
redis.call('ZREMRANGEBYSCORE', key, 0, now - window)
-- Contar ventana actual
local count = redis.call('ZCARD', key)
if count < limit then
redis.call('ZADD', key, now, now .. '-' .. math.random(1000000))
redis.call('EXPIRE', key, window)
return {1, limit - count - 1} -- permitido, restante
else
return {0, 0} -- denegado, 0 restante
end
Limitación Multinivel
Solicitud → Límite de IP (100/min)
│ pasar
↓
Verificación de Auth → Límite de clave de API (basado en nivel)
│ Free: 60/min
│ Pro: 600/min
│ Enterprise: 6000/min
↓ pasar
Límite de Endpoint (por ruta)
│ POST /subir: 10/min
│ GET /buscar: 120/min
↓ pasar
Procesar Solicitud
Cabeceras de Respuesta (Borrador Estándar IETF)
// Middleware: adjuntar cabeceras de límite
function cabecerasLimite(limite: number, restante: number, restablecerEn: number) {
return {
'RateLimit-Limit': limite.toString(),
'RateLimit-Remaining': Math.max(0, restante).toString(),
'RateLimit-Reset': Math.ceil((restablecerEn - Date.now()) / 1000).toString(),
};
}
// En respuesta 429:
res.status(429).set({
...cabecerasLimite(limite, 0, restablecerEn),
'Retry-After': Math.ceil((restablecerEn - Date.now()) / 1000).toString(),
}).json({ error: 'Demasiadas Solicitudes', reintentarDespues: restablecerEn });
Antipatrones
- Contadores en memoria en sistemas distribuidos — los límites deben compartirse entre instancias; usa Redis o equivalente
- Falta de cabecera Retry-After — las respuestas 429 sin
Retry-Afterobligan a los clientes a adivinar, provocando avalanchas - Limitación solo por IP — los límites de IP ignoran el abuso autenticado y castigan IPs compartidas (NAT, VPN); combínalo con límites por clave de API
- Corte brusco sin ráfaga — token bucket permite pequeñas ráfagas manteniendo la tasa media; la ventana fija pura es demasiado rígida
- Sin límite en APIs internas — un servicio interno que se comporte mal puede cascada-fallar tu base de datos; siempre limita
Lista de Verificación de Calidad
- Los límites usan almacenamiento distribuido (Redis/Valkey), no en memoria
- Cabeceras
RateLimit-Limit,RateLimit-Remaining,RateLimit-Reseten cada respuesta - Cabecera
Retry-Afteren respuestas 429 - Límites diferentes por nivel de autenticación (free/pro/enterprise)
- Límites por endpoint para operaciones costosas (subidas, búsquedas)
- Script Lua o pipeline atómico para incremento de contador (sin condiciones de carrera)
- Las claves de límite incluyen tanto identidad (clave API) como ámbito (endpoint)
- El panel de monitoreo muestra aciertos, denegaciones y principales consumidores de límites
- Degradación gradual: poner en cola o ralentizar en lugar de rechazar tajantemente cuando sea posible