Intermedio10 min de lectura

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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):

  • ThrottledRequests cuenta una solicitud una vez si cualquier evento dentro de ella se limitó — un PutItem sobre 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 / WriteThrottleEvents cuentan cada evento limitado — un BatchGetItem de 10 elementos son 10 eventos GetItem. Para ver las limitaciones de escritura de un GSI tienes que consultar la métrica con TableName y GlobalSecondaryIndexName a 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.

yesnoyesnoprovisionedon-demandThrottling observedThrottleEvents on a GSI(TableName + IndexName)?GSI back-pressure:scale the indexTable utilization far belowprovisioned / expected?Hot key: fix key design,split-for-heat needs timeCapacity mode?Raise capacity /auto scaling / switch modeGrew past 2x previous peak:pre-warm or spread the ramp

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

CausaQué lo solucionaQué no
Clave / partición calienteUn diseño de clave que reparta la carga (particiones calientes); tiempo para el split-for-heatSubir la capacidad de la tabla, pasarse a bajo demanda
Capacidad aprovisionadaEscalado automático, un mínimo más alto o bajo demandaSolo reintentos — añaden carga
Contrapresión del GSIEscalar el índice; cambios de índice disperso o de proyecciónEscalar la tabla base
Cuota de cuentaUn aumento en Service QuotasLos ajustes a nivel de tabla
Pico escalonado bajo demandaPrecalentar (rendimiento en caliente); repartir la rampa a lo largo de más de 30 minEsperar — 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 BatchWriteItem devuelve los elementos sin procesar en lugar de lanzar una excepción mientras algún elemento tenga éxito — revisa UnprocessedItems, 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.

Actualizado