Saltar al contenido
Underc0de /foro

Te piden diseñar un rate limiter para una API pública que corre en varias instancias. ¿Qué algoritmo elegís y cómo lo implementás?

$ interview --rol dev

Evalúa diseño de sistemas distribuidos, conocimiento de algoritmos de limitación de tasa, manejo de estado compartido y decisiones de trade-off entre precisión y rendimiento.

Respuesta

Primero aclaro requisitos: ¿qué se limita? (por API key, usuario o IP), límites por endpoint, si se toleran ráfagas y cuánta precisión hace falta.

Algoritmos:
  • Fixed window: contador por minuto. Simple, pero permite el doble del límite en el borde entre ventanas.
  • Sliding window log: guarda cada timestamp. Preciso, pero caro en memoria.
  • Sliding window counter: pondera la ventana actual y la anterior. Buen equilibrio.
  • Token bucket: el balde se recarga a tasa fija y cada request consume un token. Permite ráfagas controladas; es mi elección habitual para APIs.

Implementación distribuida: el estado no puede vivir en memoria de cada instancia, así que uso Redis compartido. La lectura y actualización del bucket deben ser atómicas, por eso uso un script Lua (o INCR + EXPIRE para fixed window) y evito el leer-y-escribir desde la app.
Código: text
key = rl:{api_key}
lua: calcular tokens según el tiempo transcurrido, restar 1 si hay, guardar con TTL

Decisiones clave:
  • Fail-open vs fail-closed si Redis cae: normalmente fail-open con un límite local de respaldo, para no tirar la API.
  • Latencia: Redis cerca de la app; para tráfico altísimo, contadores locales que sincronizan periódicamente, aceptando algo de imprecisión.
  • Respuesta: HTTP 429 con Retry-After y headers de límite restante.
  • Capas: un límite grueso en el gateway/WAF contra abuso y uno fino por plan del cliente en la app.
  • Observabilidad: métricas de 429 por cliente para ajustar límites.

Desde seguridad, mitiga fuerza bruta y scraping, pero limitar por IP sola es débil (NAT, IPs rotativas); conviene combinarlo con identidad.

Errores comunes

Guardar contadores en memoria local con múltiples instancias. Hacer GET y SET separados en Redis, creando una race condition. No definir qué pasa si el almacén compartido falla.

Redactado con el asistente Underc0de IA. Actualizado el 13/11/2026. ¿Ves un error? Contanos en el foro.

Grupo de WhatsApp