El mecanismo de throttling de las API de AWS - El algoritmo Token Bucket y la verdad detrás del error 429

Explicamos cómo el rate limiting de las API de AWS se implementa con el algoritmo Token Bucket, el concepto de burst capacity, las diferencias en los límites según el servicio, y las medidas prácticas para evitar el throttling.

¿Por qué AWS aplica rate limiting a todas las API?

Todas las API de AWS tienen configurado un rate limit (throttling) por cuenta y por región. La respuesta que se recibe al superar el límite varía según el servicio y se divide, a grandes rasgos, en tres familias. Primero, la API de EC2 devuelve RequestLimitExceeded con HTTP 503 (Service Unavailable). Segundo, API Gateway devuelve HTTP 429 (Too Many Requests). Tercero, las API de muchos servicios de AWS devuelven ThrottlingException con HTTP 400 (Bad Request). Es decir, si se simplifica como "el throttling siempre llega como 429", se pierden las familias que responden con 503 o 400. Lo más seguro es decidir el reintento no solo por el código de estado HTTP, sino también junto con el código de error (RequestLimitExceeded / ThrottlingException / TooManyRequestsException, entre otros). El rate limiting tiene dos propósitos. Primero, garantizar la equidad en un entorno multi-tenant. Si una cuenta realiza llamadas masivas a la API, afecta el rendimiento de otras cuentas que comparten la misma infraestructura. El rate limiting es un guardrail que previene el "problema del vecino ruidoso". Segundo, la protección del propio cliente. Hay casos donde un bug en la aplicación causa un bucle infinito que llama a la API decenas de miles de veces por segundo. Sin rate limiting, esta ejecución descontrolada resultaría en facturas elevadas. El rate limiting funciona como una red de seguridad que detecta tempranamente ejecuciones no intencionadas. Según el servicio, los valores de rate limit se pueden visualizar en Service Quotas y solicitar su aumento mediante una solicitud de incremento de cuota. Sin embargo, no todos los servicios ni todos los límites pueden visualizarse o ampliarse de forma uniforme. Hay límites, como los valores de throttling de la API de EC2, en los que es necesario solicitar acceso para consultar el valor actual o para pedir su aumento, por lo que en la fase de diseño conviene pensar en dos niveles: si aparece en Service Quotas se puede comprobar ahí y, si no aparece, se confirma a través de Support.

Cómo funciona el algoritmo Token Bucket

El throttling de las API de AWS se implementa con el algoritmo Token Bucket. Este algoritmo funciona con un bucket (contenedor) donde se reponen tokens (permisos) a una velocidad constante, y cada solicitud de API consume un token. Cuando el bucket está vacío, las solicitudes son rechazadas. Veámoslo con valores reales (las cifras siguientes son las indicadas en la documentación oficial a fecha de agosto de 2026 y pueden variar según la cuenta o la región). La documentación de throttling de la API de EC2 indica que el bucket de tokens de solicitud para las acciones no mutantes sin filtros ni paginación (como DescribeInstances) tiene una capacidad máxima de 50 tokens y una tasa de reposición de 10 tokens por segundo, mientras que el resto de acciones no mutantes estándar tiene una capacidad máxima de 100 tokens y una tasa de reposición de 20 tokens por segundo. Tomando DescribeInstances como ejemplo, con el bucket lleno se pueden enviar instantáneamente 50 solicitudes (burst). Una vez agotadas, la tasa de reposición marca el ritmo y se estabiliza en 10 solicitudes por segundo. Lo que hay que tener claro aquí es el reparto de funciones. La capacidad máxima del bucket determina cuánto se puede enviar de golpe durante el burst, y la tasa de reposición determina el ritmo permitido en régimen estable. Si se confunde esta correspondencia, en la que burst equivale a capacidad y régimen estable equivale a tasa de reposición, las estimaciones se desvían varias veces. El burst capacity es un buffer que absorbe picos de corta duración. En patrones donde se llaman APIs de forma masiva al iniciar una aplicación, esta capacidad es la que entra en juego. Por el contrario, en un proceso batch que se ejecuta durante mucho tiempo, la capacidad solo ayuda en el primer instante y el throughput efectivo lo determina la tasa de reposición.

Granularidad del throttling que varía según el servicio

La granularidad del throttling varía significativamente según el servicio. Las API de EC2 tienen rate limits individuales configurados por acción de API. DescribeInstances y RunInstances se gestionan en buckets separados, por lo que el throttling de DescribeInstances no afecta a RunInstances. Además, EC2 tiene un "rate limit de recursos" que constituye un eje distinto del rate limit de solicitudes. Las acciones que crean o modifican recursos, como RunInstances, consumen un bucket de tokens de recursos además del bucket del número de solicitudes. En el caso de RunInstances, el bucket de tokens de recursos tiene una capacidad máxima de 1,000 tokens y una tasa de reposición de 2 tokens por segundo (cifras indicadas en la documentación oficial a fecha de agosto de 2026). Lo importante es que este bucket se reduce en proporción al número de recursos sobre los que se opera, no al número de llamadas a la API. Si con una sola llamada a RunInstances se lanzan 100 instancias, se consumen 100 tokens de recursos, por lo que se puede sufrir throttling por el lado del rate limit de recursos aunque el número de llamadas sea de unas pocas. En la automatización que lanza o elimina instancias de forma masiva, este segundo eje debe incluirse siempre en la estimación. Por otro lado, el throttling de DynamoDB se aplica a nivel de tabla. Las solicitudes que exceden la capacidad provisionada de la tabla (RCU/WCU) son throttled. Esto es diferente del throttling a nivel de API; es una limitación de throughput de acceso a datos. El límite de ejecución concurrente de Lambda también es un tipo de throttling. La cuota predeterminada de ejecuciones concurrentes por cuenta es de 1,000, pero las cuentas recién creadas comienzan con una cuota reducida que AWS eleva automáticamente en función del uso (según la documentación oficial a fecha de agosto de 2026). Por eso, si se diseña asumiendo que incluso una cuenta nueva puede llegar a 1,000 desde el principio, se tropieza con un throttling inesperado en las pruebas de carga. Lo más fiable es comprobar el valor actual en Service Quotas. API Gateway tiene un rate limit a nivel de cuenta de 10,000 solicitudes por segundo (predeterminado), y además permite configuraciones de throttling individuales por API, por stage y por método. Este throttling multicapa permite controlar que el acceso concentrado a un endpoint específico no afecte a otros endpoints.

Backoff exponencial y jitter - La estrategia de reintentos que el SDK realiza automáticamente

La respuesta correcta al recibir un error de throttling es un reintento combinando backoff exponencial (Exponential Backoff) y jitter. El backoff exponencial es una estrategia que aumenta el intervalo de reintento exponencialmente: 1 segundo, 2 segundos, 4 segundos, 8 segundos. Esto alivia gradualmente la presión de solicitudes sobre el servicio que está siendo throttled. El jitter es una técnica que añade variación aleatoria al intervalo de reintento. Solo con backoff exponencial, múltiples clientes throttled simultáneamente reintentarían al mismo tiempo, causando throttling nuevamente - el problema del "thundering herd". Al añadir jitter, los tiempos de reintento se distribuyen. Los SDK de AWS implementan automáticamente esta estrategia de reintentos internamente. El valor predeterminado del AWS SDK for JavaScript v3 es "un máximo de 3 intentos", lo que significa 1 solicitud inicial más un máximo de 2 reintentos. Si se lee erróneamente como "reintentar 3 veces", se estima un intento más de los que realmente se producen, así que conviene tener cuidado. Hay excepciones: los clientes de DynamoDB y DynamoDB Streams incorporan una configuración más agresiva de 4 intentos y un backoff base de 25 milisegundos (son los valores del nuevo esquema de reintentos de 2026, que está pasando gradualmente de ser una opción de activación voluntaria a ser el valor predeterminado). El comportamiento de reintento no es algo propio de un lenguaje concreto: como configuración común a todos los AWS SDK se definen tres modos, standard / adaptive / legacy. La generación actual de SDK y la CLI usan standard de forma predeterminada, tras abandonar el antiguo modo legacy. adaptive es un modo en el que el cliente aprende su propia tasa de envío y la reduce, una opción para procesos en los que el throttling es constante. Además, standard y adaptive incluyen un control de volumen total llamado "retry quota". Se trata de un bucket de tokens que el cliente del SDK mantiene internamente: cada reintento consume tokens y estos se recuperan poco a poco cuando las solicitudes tienen éxito. Cuando los tokens se agotan, los reintentos se interrumpen. Es decir, el bucket de tokens que da título a este artículo se utiliza no solo para el rate limiting del lado del servicio, sino también como mecanismo del lado del cliente para no dispersar reintentos de forma indiscriminada. Si se llaman las API directamente sin usar el SDK, es necesario implementar estos mecanismos de reintento por cuenta propia.

Patrones de diseño para evitar el throttling preventivamente

Es más ideal diseñar para no generar throttling en primer lugar que reintentar después de que ocurra. El primer patrón es la reducción de llamadas a API. En lugar de llamar a DescribeInstances de EC2 cada segundo para monitorear el estado de las instancias, usando eventos de EventBridge (EC2 Instance State-change Notification) se reciben notificaciones solo cuando hay cambios de estado. La transición de polling a event-driven reduce drásticamente el número de llamadas a API. El segundo patrón es el uso de caché. La información que no cambia frecuentemente (configuración de cuenta, lista de regiones, etc.) se cachea localmente para reducir las llamadas a API. El tercer patrón es el uso de API por lotes. BatchGetItem de DynamoDB puede obtener hasta 100 items en una sola llamada a API. Comparado con llamar GetItem 100 veces individualmente, reduce las llamadas a API en un 99%. ListObjectsV2 de S3 también puede obtener hasta 1,000 objetos en una sola solicitud con el parámetro MaxKeys.

Referencias (recursos oficiales de AWS)

Las fuentes primarias de esta página son el sitio web y la documentación oficiales de AWS. Consulta las páginas oficiales siguientes para conocer las especificaciones y los precios más recientes.

Si esta página y la documentación oficial difieren, prevalece la documentación oficial.

Compartir