Rate Limiting y Throttling en APIs: Estrategias para Producción · Daniel Tinizaray

Rate Limiting y Throttling en APIs: Estrategias para Producción · Daniel Tinizaray

Toda API pública o multi-tenant termina necesitando límites de tasa. Sin ellos, un solo cliente mal comportado (o un bug en un script de integración) puede agotar conexiones de base de datos, disparar la factura de cómputo y degradar la experiencia de todos los demás. El rate limiting no es una función opcional: es una propiedad de diseño del backend.

Limitar no es castigar: es proteger la capacidad

Un límite de tasa bien diseñado cumple tres objetivos: protege la infraestructura de picos abusivos, garantiza fairness entre clientes (evita el problema del noisy neighbor) y convierte la sobrecarga en una señal explícita y predecible en lugar de timeouts misteriosos. La diferencia entre un buen y un mal sistema de rate limiting suele estar en la comunicación: un 429 con headers claros es útil; un 503 genérico, no.

Algoritmos: cuál elegir según el caso

  • Fixed window: contador simple por ventana de tiempo (ej. 100 req/min). Barato y fácil, pero sufre el problema del borde: un cliente puede enviar 2x el límite justo en la frontera de dos ventanas.
  • Token bucket: los tokens se regeneran a ritmo constante y cada request consume uno. Permite bursts controlados, ideal para APIs públicas con cuotas por plan.
  • Sliding window: ventana continua que elimina el problema del borde. Mayor precisión a cambio de más estado; recomendado para endpoints sensibles como pagos o búsquedas costosas.
  • Leaky bucket: suaviza la salida a ritmo constante, útil para proteger servicios frágiles aguas abajo (ej. pipelines de webhooks).
Regla práctica: token bucket para APIs de desarrolladores, sliding window para límites estrictos por tenant, leaky bucket para proteger consumidores. No hay un algoritmo universal; hay trade-offs por endpoint.

El problema distribuido

En un solo proceso, un contador en memoria basta. Pero en producción casi siempre hay múltiples réplicas detrás de un balanceador, y cada una tendría su propia visión del contador. La solución estándar es externalizar el estado a un store compartido como Redis, donde cada instancia incrementa atómicamente el contador. Con Lua scripts o comandos como INCR + EXPIRE se logra una operación atómica y rápida:

// Contador distribuido en Redis (ventana fija)
const key = `rl:${clientId}:${Math.floor(Date.now() / 60000)}`;
const count = await redis.incr(key);
if (count === 1) await redis.expire(key, 60);
if (count > limit) return res.status(429).json({ error: 'rate_limited' });

Para altas tasas de tráfico, el sliding window logarítmico en Redis (con sorted sets y ZREMRANGEBYSCORE) ofrece precisión con memoria acotada. Si la latencia del store compartido preocupa, un patrón híbrido funciona bien: contador local aproximado en cada nodo + sincronización periódica, aceptando un pequeño margen de error a cambio de menos round-trips.

Comunicación: headers y degradación elegante

  • Usa los headers estándar RateLimit-Limit, RateLimit-Remaining y RateLimit-Reset (y Retry-After en cada 429).
  • Documenta los límites por plan y por endpoint: un límite invisible se siente como un bug.
  • Aplica límites diferenciados: por API key, por tenant, y límites más estrictos en endpoints costosos (uploads, búsquedas, inferencia).
  • Considera grace periods o límites con pequeño margen para clientes históricamente bien comportados; el throttling duro debe ser la excepción.

Errores comunes

Limitar solo en el gateway y no en los servicios (un bypass interno anula todo), usar la IP como clave única detrás de proxies (agrupa usuarios legítimos), no persistir contadores en redeployments, y olvidar monitorear la tasa de 429 como señal de producto: un pico de rechazos indica un cliente que necesita un plan superior o una integración mal implementada. El rate limiting, bien instrumentado, es también una fuente de datos comerciales.

Conclusión: empieza simple (token bucket en el gateway + Redis), mide, y refina por endpoint. La complejidad en rate limiting se gana con datos, no por adelantado.


¿Te gustó este artículo?

Si estás lidiando con estos desafíos en tu empresa, hablemos. Sin compromiso. 30 minutos para entender tu situación.

Agenda una llamada gratuita →