Limitación de DynamoDB — por qué ocurre y cómo solucionarla
La limitación es DynamoDB diciéndote que has alcanzado un límite — pero hay cuatro límites distintos, tres excepciones distintas, y la solución para una causa empeora otra. Subir la capacidad de la tabla no hace nada por una clave caliente; pasarse a bajo demanda tampoco hace nada por una clave caliente y aún puede limitar el tráfico por sus propias reglas. Esta guía es el paraguas: qué límite has alcanzado de verdad, cómo lo distinguen las métricas y la solución que corresponde a cada causa.
¿Por qué DynamoDB limita mis solicitudes?
Por una de cuatro razones documentadas: una única partición superó su límite fijo por partición de 3000 unidades de lectura o 1000 unidades de escritura por segundo (una clave caliente — ocurre en los dos modos de capacidad); la tabla superó sus RCU/WCU aprovisionadas (modo aprovisionado); la cuenta superó su cuota de rendimiento a nivel de región; o una tabla bajo demanda creció más rápido que el doble de su pico anterior dentro de 30 minutos. La solución depende de cuál fuera, así que diagnostica antes de redimensionar nada.
Los cuatro escenarios de limitación
La propia página de resolución de problemas de AWS divide la limitación en exactamente cuatro casos:
- Rendimiento del rango de claves (partición) superado — los dos modos. Cada partición está diseñada para un máximo de 3000 unidades de lectura y 1000 unidades de escritura por segundo (documentación de la clave de partición), y el tamaño del elemento cuenta contra ese límite. Ningún ajuste a nivel de tabla lo sube; solo el diseño de la clave lo reparte. Este es el caso de la partición caliente, y la tabla puede parecer masivamente infrautilizada mientras limita el tráfico.
- Rendimiento aprovisionado superado — modo aprovisionado. El consumo superó las RCU/WCU aprovisionadas de la tabla (o de un GSI), y el colchón de ~5 minutos de capacidad de ráfaga se agotó. La escalera de soluciones está en el lado de la capacidad: el escalado automático, un aprovisionamiento mayor o un cambio de modo.
- Cuota a nivel de cuenta superada. Las cuotas de cuenta por región limitan el rendimiento total — por defecto 40 000 unidades de lectura y 40 000 de escritura por tabla, y en modo aprovisionado 80 000 RCU y 80 000 WCU por cuenta (cuotas); son valores iniciales por defecto, ajustables mediante Service Quotas, y las tablas bajo demanda no tienen cuota de rendimiento a nivel de cuenta.
- Rendimiento máximo bajo demanda superado. El modo bajo demanda acomoda al instante hasta el doble del pico anterior; crece más allá del doble dentro de 30 minutos y puede limitar el tráfico (documentación de bajo demanda). Las tablas bajo demanda nuevas sostienen 4000 escrituras/s y 12 000 lecturas/s de fábrica. Para un pico escalonado planificado (un lanzamiento, una rebaja, una migración), precalienta la tabla con el rendimiento en caliente en lugar de confiar en que la rampa sea gradual.
Las tres excepciones y el campo que nombra la causa
ProvisionedThroughputExceededException— limitación de capacidad en modo aprovisionado: «has superado el rendimiento aprovisionado máximo permitido para una tabla o para uno o varios índices secundarios globales». Los detalles, en la página dedicada del error.ThrottlingException— operaciones del plano de control emitidas demasiado rápido y, en tablas bajo demanda, cualquier operación del plano de datos cuya tasa sea demasiado alta (esa es la excepción detrás de la regla del doble del pico — mira la página del error de bajo demanda y ThrottlingException).RequestLimitExceeded— límites de rendimiento a nivel de cuenta: territorio de «contacta con AWS Support», cubierto en su página de error.
Las tres están marcadas como reintentables, y las tres llevan ahora valores
estructurados de ThrottlingReason con la forma recurso + operación + límite —
TableReadProvisionedThroughputExceeded,
IndexWriteKeyRangeThroughputExceeded, TableWriteAccountLimitExceeded, etcétera
(referencia de errores).
Lee la razón, no solo la clase de la excepción: nombra el recurso (tabla o índice), la
dirección de la operación y cuál de los cuatro límites has alcanzado — que es
exactamente el diagnóstico. Una salvedad que la propia documentación obliga a hacer:
las páginas de AWS difieren en si la limitación por cuota de cuenta aparece como
RequestLimitExceeded o como una ThrottlingException con una razón
AccountLimitExceeded, así que apoya tu manejo en la cadena de la razón.
Qué absorbe la carga antes de que te limiten
Dos mecanismos integrados suavizan los límites, y conocer sus bordes explica el «ayer funcionaba»:
- La capacidad de ráfaga retiene hasta cinco minutos (300 segundos) de capacidad de lectura y escritura sin usar para los picos — pero DynamoDB también puede consumirla en tareas de mantenimiento en segundo plano «sin previo aviso», y AWS señala explícitamente que los detalles pueden cambiar. No diseñes contando con la ráfaga; trátala como suerte.
- La capacidad adaptativa desplaza el rendimiento hacia las particiones calientes de forma automática e instantánea, y puede aislar un elemento muy accedido en su propia partición — pero solo «siempre que el tráfico no supere la capacidad aprovisionada total de tu tabla ni la capacidad máxima de la partición». Reequilibra el sesgo; nunca levanta el techo de 3000/1000 por partición, y no dividirá las colecciones de elementos cuando la tabla tiene un LSI. Las páginas actuales de resolución de problemas de AWS se apoyan en el split-for-heat (la división de particiones bajo calor sostenido), que lleva tiempo y no ayuda con una única clave caliente.
Diagnostícala desde las métricas
CloudWatch separa las solicitudes de los eventos, y la distinción hace el diagnóstico (referencia de métricas):
ThrottledRequestscuenta una solicitud una vez si cualquier evento dentro de ella se limitó — unPutItemsobre una tabla con tres GSI es una solicitud pero cuatro eventos de escritura. En un lote, solo se incrementa si todos los elementos se limitaron.ReadThrottleEvents/WriteThrottleEventscuentan cada evento limitado — unBatchGetItemde 10 elementos son 10 eventosGetItem. Para ver las limitaciones de escritura de un GSI tienes que consultar la métrica conTableNameyGlobalSecondaryIndexNamea la vez — así es como la contrapresión del GSI se esconde de los paneles a nivel de tabla.- Las más recientes métricas de eventos específicas por razón
(
WriteProvisionedThroughputThrottleEvents,ReadKeyRangeThroughputThrottleEvents,…AccountLimitThrottleEvents,…MaxOnDemandThroughputThrottleEvents) reparten los recuentos entre esas mismas cuatro causas — si tu región las muestra, responden directamente a la pregunta de «qué límite».
Una trampa: los SDK reintentan automáticamente las solicitudes limitadas — el modo de reintento estándar hace 3 intentos en total por defecto (el despliegue opcional de reintentos de 2026 lleva a los clientes de DynamoDB a 4 intentos con retardos más ajustados). Por eso una limitación ligera aparece como latencia, no como errores; vigila las métricas de limitación, no solo tus registros de excepciones.
Contrapresión del GSI: la limitación que apunta a la tabla equivocada
Si algún GSI no puede absorber la amplificación de escritura, «DynamoDB limita las
escrituras a la tabla base para mantener la coherencia de los datos»
(documentación de la limitación de los GSI)
— incluso cuando a la tabla base le sobra capacidad. El ResourceArn de la excepción
apunta al índice, pero la operación que falló es tu escritura en la tabla base. Cada
índice necesita su propio plan de capacidad (y su propia
política de escalado automático);
por qué un GSI limita las escrituras de la tabla base
recorre la mecánica.
Empareja la solución con la causa
| Causa | Qué lo soluciona | Qué no |
|---|---|---|
| Clave / partición caliente | Un diseño de clave que reparta la carga (particiones calientes); tiempo para el split-for-heat | Subir la capacidad de la tabla, pasarse a bajo demanda |
| Capacidad aprovisionada | Escalado automático, un mínimo más alto o bajo demanda | Solo reintentos — añaden carga |
| Contrapresión del GSI | Escalar el índice; cambios de índice disperso o de proyección | Escalar la tabla base |
| Cuota de cuenta | Un aumento en Service Quotas | Los ajustes a nivel de tabla |
| Pico escalonado bajo demanda | Precalentar (rendimiento en caliente); repartir la rampa a lo largo de más de 30 min | Esperar — el doble del pico se restablece despacio |
Hazlo en DynoTable
La mayoría de la limitación autoinfligida empieza con lecturas que cuestan más de lo
que parecen: un Scan con filtro consume la lectura completa igualmente. La vista
previa del coste antes de ejecutar de DynoTable muestra si una sentencia se convierte
en un Query o en un Scan, el índice al que llega y un coste de lectura estimado
antes de que lo gastes — la solución más barata a la limitación es la lectura cara que
no ejecutaste. La guía de Scan frente a Query cubre la
diferencia; la calculadora de tamaño de elemento
gratuita convierte un elemento real en los números de RCU/WCU en los que se miden los
límites de arriba.
Trampas y próximos pasos
- Los reintentos amplifican la sobrecarga. La espera exponencial viene integrada en los SDK, pero un bucle de reintentos apretado a nivel de aplicación por encima de los reintentos del SDK multiplica la presión justo sobre la partición que está sufriendo.
- Los lotes ocultan la limitación parcial. Un
BatchWriteItemdevuelve los elementos sin procesar en lugar de lanzar una excepción mientras algún elemento tenga éxito — revisaUnprocessedItems, no solo las excepciones. - La vista a nivel de tabla miente sobre los GSI. Grafica siempre los eventos de limitación por índice; los paneles de la tabla base se ven limpios durante la contrapresión.
- Las soluciones de capacidad tardan minutos; el diseño de la clave es para siempre. El escalado automático reacciona en ~5 minutos, los aumentos de cuota requieren un ticket de soporte, pero una clave caliente te sigue a todos los modos de capacidad — invierte el esfuerzo donde se acumula: cómo funcionan las claves de partición.
Descarga DynoTable para ver el plan de Scan frente a Query de cada consulta y su coste de lectura antes de que se ejecute contra tu capacidad.