rendimiento-api · limitacion-de-tasa · algoritmos · backend
Algoritmos de Limitación de Tasa: Una Guía Técnicamente Conservadora para Desarrolladores Independientes
Una comparación práctica de los algoritmos de limitación de tasa de ventana fija, ventana deslizante y bucket de tokens: qué compensan, cuándo usar cada uno y cómo implementar un throttling justo sin complicar tu stack.
Publicado:
Algoritmos de Limitación de Tasa: Una Guía Técnicamente Conservadora para Desarrolladores Independientes
La limitación de tasa es uno de esos problemas de infraestructura que parecen simples hasta que realmente tienes que construirlos. Quieres limitar las solicitudes por usuario, por IP o por clave de API. Agregas un contador, devuelves 429 cuando lo excede, y das el tema por resuelto. Pero en el momento en que lo envías a producción, pasan tres cosas: los usuarios legítimos son throttled injustamente, tus contadores filtran memoria, o tu implementación “simple” colapsa bajo tráfico en ráfaga.
Esta guía recorre los tres algoritmos de limitación de tasa más comunes—ventana fija, ventana deslizante y bucket de tokens—para que puedas elegir el correcto para tu API sin caer en las trampas clásicas.
Por Qué Importa la Elección del Algoritmo
Los algoritmos de limitación de tasa difieren en tres dimensiones que importan a los equipos indie: precisión, costo de memoria y comportamiento de ráfaga. Un contador de ventana fija es barato y fácil pero permite ráfagas en los límites de ventana. Una ventana deslizante es más precisa pero requiere más almacenamiento. Un bucket de tokens maneja ráfagas con gracia pero necesita un ajuste cuidadoso para evitar la inanición.
Tu elección depende de qué estás protegiendo. Si estás limitando intentos de inicio de sesión para prevenir ataques de credential stuffing, la precisión importa más que la tolerancia a ráfagas. Si estás protegiendo un endpoint de búsqueda contra abuso, un bucket de tokens puede ser la opción correcta. Si estás construyendo una API pública con tarifas por nivel, la equidad entre clases de usuario se convierte en la prioridad.
Contadores de Ventana Fija
El algoritmo de ventana fija divide el tiempo en intervalos discretos—digamos, un minuto—y cuenta las solicitudes dentro de cada intervalo. Cuando el contador excede el límite, las solicitudes subsiguientes se rechazan hasta que comienza la siguiente ventana.
Cómo funciona: Almacenas un contador claveado por (user_id, inicio_ventana). En cada solicitud, incrementas el contador. Si excede el límite, devuelves 429. Cuando la ventana expira, borras la clave y empiezas de nuevo.
La compensación: Los contadores de ventana fija son los más simples de implementar y los más baratos en términos de memoria. Solo almacenas un entero por usuario por ventana. Pero tienen un defecto bien conocido: el problema del límite. Un usuario puede hacer el doble de la tasa permitida en un solo segundo si sus solicitudes atraviesan dos ventanas. Por ejemplo, si el límite es 100 solicitudes por minuto, un usuario podría enviar 100 solicitudes en el último segundo de la ventana 1 y otras 100 en el primer segundo de la ventana 2—efectivamente duplicando su tasa en el límite.
Cuándo usarlo: Los contadores de ventana fija funcionan bien para limitación de tasa de bajo riesgo donde ráfagas ocasionales son aceptables. También son un punto de partida razonable si estás implementando limitación de tasa por primera vez y quieres enviar algo rápido. Las reglas básicas de limitación de tasa de Cloudflare usan un enfoque de ventana fija por debajo, lo cual explica por qué son rápidas de configurar pero a veces parecen imprecisas en los bordes.
Contadores de Ventana Deslizante
El algoritmo de ventana deslizante mejora el de ventana fija rastreando solicitudes a través de una ventana de tiempo rodante en lugar de intervalos discretos. En lugar de preguntar “cuántas solicitudes en este minuto?” pregunta “cuántas solicitudes en los últimos 60 segundos?”
Cómo funciona: Hay dos implementaciones comunes. La primera almacena un registro con marca de tiempo de cada solicitud y cuenta cuántas caen dentro de la ventana en cada verificación. Esto es preciso pero intensivo en memoria—almacenas una marca de tiempo por cada solicitud. La segunda aproximación, más práctica, usa múltiples ventanas fijas e interpola entre ellas. Por ejemplo, podrías almacenar contadores para el minuto actual y el anterior, luego estimar el conteo de ventana como un promedio ponderado. Esto se llama contador de ventana deslizante o registro de ventana deslizante, y es lo que usan muchos sistemas en producción.
La compensación: Los contadores de ventana deslizante son más precisos que los de ventana fija—eliminan el problema de ráfaga en los límites. Pero cuestan más en memoria y cómputo. El enfoque interpolado reduce la memoria comparado con un registro completo de marcas de tiempo pero aún requiere almacenar múltiples contadores por usuario. Si estás limitando tasa a escala para millones de usuarios, este costo de memoria se acumula rápido.
Cuándo usarlo: Los contadores de ventana deslizante son la opción correcta cuando la precisión importa y puedes permitirte el costo de memoria. Son comúnmente usados para proteger endpoints sensibles como inicio de sesión o restablecimiento de contraseña, donde el problema de ráfaga en los límites podría permitir que un atacante duplique su tasa efectiva. La Limitación de Tasa Avanzada de Cloudflare, que cuenta solicitudes basándose en características HTTP más allá de solo la dirección IP, usa lógica de ventana deslizante internamente para proporcionar throttling más preciso.
Algoritmo de Bucket de Tokens
El algoritmo de bucket de tokens es el más flexible de los tres. En lugar de contar solicitudes, rastrea tokens. Un bucket contiene un número máximo de tokens y se rellena a una tasa constante. Cada solicitud consume un token. Si el bucket está vacío, la solicitud se rechaza.
Cómo funciona: Almacenas la cantidad de tokens restantes en el bucket y el último tiempo de relleno. En cada solicitud, calculas cuántos tokens deberían haberse añadido desde la última solicitud basado en el tiempo transcurrido, limitas el total al máximo del bucket, luego restas un token si está disponible. Si no quedan tokens, devuelves 429.
La compensación: Los buckets de tokens manejan ráfagas con gracia porque el bucket puede acumular tokens durante períodos de inactividad. Un usuario que no ha hecho solicitudes por un tiempo tendrá un bucket lleno y puede hacer ráfagas hasta la capacidad del bucket. Esto es tanto una característica como un problema—permite tráfico legítimo en ráfaga pero también puede permitir que un solo usuario consuma recursos desproporcionados si el bucket es demasiado grande.
La tasa de relleno determina el throughput sostenido, mientras que la capacidad del bucket determina el tamaño de la ráfaga. Ajustar ambos parámetros es esencial. Un bucket que se rellena demasiado lento inanica a los usuarios; un bucket que se rellena demasiado rápido anula el propósito de la limitación de tasa.
Cuándo usarlo: Los buckets de tokens son ideales cuando necesitas permitir ráfagas controladas mientras mantienes una tasa promedio constante. Son ampliamente usados en gateways de API y lógica de borde de CDN. La API de Limitación de Tasa de Cloudflare Workers, por ejemplo, está respaldada por infraestructura de bucket de tokens. AWS Elastic Load Balancing también usa el algoritmo de bucket de tokens para su throttling de API, con buckets separados para diferentes versiones de API y tipos de acción.
Limitación de Tasa Justa
Independientemente del algoritmo que elijas, la equidad es el problema más difícil. La limitación de tasa justa significa que los usuarios legítimos no son penalizados por el comportamiento de clientes maliciosos o mal configurados que comparten el mismo espacio de identidad.
El problema de la IP: La limitación de tasa tradicional basada en IP se rompe cuando múltiples usuarios comparten una dirección IP. NAT a escala de operador, proxies corporativos y redes móviles significan que miles de usuarios pueden compartir una sola IP pública. Limitar esa IP limita a todos. Cloudflare lo señaló explícitamente en su anuncio de Limitación de Tasa Avanzada: “Las IPs rara vez son estáticas; hoy en día, los operadores móviles usan traducción de direcciones a escala de operador (CGNAT) para compartir la misma IP entre miles de dispositivos o usuarios individuales.”
Señales de identidad mejores: La limitación de tasa justa requiere contar contra identificadores que mapean uno a uno—or lo más cercano posible—a usuarios individuales. Las claves de API son el estándar de oro para APIs autenticadas. Los IDs de usuario de sistemas de autenticación funcionan bien para limitación de tasa basada en sesión. Para endpoints no autenticados, puedes combinar múltiples señales: user agent, valores de cookies y patrones de solicitud. La Limitación de Tasa Avanzada de Cloudflare permite contar por URI, método, headers, cookies y campos del body, dándote la flexibilidad de construir reglas que apuntan patrones específicos de abuso sin daño colateral al tráfico legítimo.
Límites por nivel: La equidad también significa diferentes límites para diferentes clases de usuario. Un nivel gratuito y un nivel pagado deben tener límites de tasa diferentes. Esto es straightforward de implementar: incluye el nivel del usuario en tu clave de limitación de tasa y configura límites separados por nivel. La API de Limitación de Tasa de Cloudflare Workers soporta esto nativamente—puedes definir diferentes límites para diferentes namespaces y aplicarlos basándose en atributos de usuario.
Lista de Verificación de Implementación
Antes de enviar limitación de tasa a producción, verifica estos elementos:
- Elige el algoritmo correcto para tu modelo de amenaza. Ventana fija para simplicidad, ventana deslizante para precisión, bucket de tokens para tolerancia a ráfagas.
- Elige la clave de identidad correcta. Clave de API o ID de usuario para endpoints autenticados. Múltiples señales para los no autenticados.
- Establece límites sensatos. Empieza conservador y ajusta basado en tráfico observado. AWS recomienda monitorear eventos de throttling y ajustar la lógica de reintentos antes de solicitar aumentos de cuota.
- Maneja las respuestas 429 con gracia. Implementa backoff exponencial con jitter. La guía de AWS sobre timeouts, reintentos y backoff con jitter es la referencia estándar aquí.
- Monitorea y alerta. Rastrea hits de limitación de tasa, solicitudes rechazadas y falsos positivos. Los dashboards de CloudWatch y el análisis de Cloudflare pueden ayudarte a detectar problemas antes de que impacten a los usuarios.
- Planifica para escala. Si estás limitando tasa para millones de usuarios, considera implementaciones distribuidas usando Redis o un servicio de limitación de tasa dedicado en lugar de contadores en proceso.
FAQ
P: ¿Puedo simplemente usar una biblioteca en lugar de implementar esto yo mismo?
Sí. La mayoría de los frameworks modernos tienen middleware de limitación de tasa. La pregunta es si el algoritmo por defecto de la biblioteca y su configuración coinciden con tus necesidades. Si estás construyendo algo personalizado, entender estos algoritmos te ayuda a configurar la biblioteca correctamente y depurar problemas cuando surjan.
P: ¿Cómo manejo la limitación de tasa distribuida entre múltiples servidores?
Necesitas un almacén de estado compartido. Redis es la opción más común—usa INCR con EXPIRE para contadores de ventana fija, o un sorted set para registros de ventana deslizante. Los buckets de tokens en un sistema distribuido requieren coordinación cuidadosa; considera usar un servicio de limitación de tasa centralizado o una biblioteca como Bucket4j que maneja el estado distribuido por ti.
P: ¿Cuál es la diferencia entre limitación de tasa y throttling?
La limitación de tasa capta el número de solicitudes durante un período de tiempo. El throttling es un término más amplio que incluye la limitación de tasa pero también abarca control de congestión, retroalimentación y otras técnicas para manejar la carga. En la práctica, los términos a menudo se usan indistintamente.
P: ¿Debería limitar la tasa en el gateway de API o en la aplicación?
Ambos. La limitación de tasa en el gateway de API protege tu infraestructura de ataques volumétricos y reduce la carga antes de que las solicitudes alcancen tu aplicación. La limitación de tasa a nivel de aplicación te da control más fino basado en lógica de negocio—diferentes endpoints, niveles de usuario y patrones de abuso. Cloudflare y AWS WAF proporcionan limitación de tasa a nivel de gateway; tu aplicación debe imponer sus propios límites para protección específica de endpoints.
Fuentes
- Mejores prácticas de limitación de tasa - Cloudflare WAF
- API de Limitación de Tasa - Cloudflare Workers
- Presentando Limitación de Tasa Avanzada - Blog de Cloudflare
- Throttling de solicitudes para la API de Elastic Load Balancing - AWS
- Gestionando y monitoreando throttling de API en tus cargas de trabajo - Blog de Operaciones en la Nube de AWS
- Estrategias de Limitación de Tasa para Aplicaciones Serverless - Blog de Arquitectura de AWS