Aprende qué es Amazon DynamoDB, cómo funciona su modelo NoSQL y patrones de diseño prácticos para sistemas escalables y de baja latencia.

Amazon DynamoDB es un servicio de base de datos NoSQL totalmente gestionado de AWS, diseñado para aplicaciones que necesitan lecturas y escrituras con latencia consistentemente baja a prácticamente cualquier escala. “Totalmente gestionado” significa que AWS se encarga del trabajo de infraestructura: aprovisionamiento de hardware, replicación, parcheo y muchas tareas operativas, de modo que los equipos pueden centrarse en entregar funcionalidades en lugar de ejecutar servidores de bases de datos.
En su núcleo, DynamoDB almacena datos como items (filas) dentro de tablas, pero cada item puede tener atributos flexibles. El modelo de datos se entiende mejor como una mezcla de:
Los equipos eligen DynamoDB cuando quieren rendimiento predecible y operaciones más sencillas para cargas que no encajan bien en joins relacionales. Se usa comúnmente para microservicios (cada servicio maneja sus propios datos), apps serverless con tráfico explosivo y sistemas orientados a eventos que reaccionan a cambios en los datos.
Este artículo recorre los bloques de construcción (tablas, claves e índices), cómo modelar según los patrones de acceso (incluido el diseño de tabla única), cómo funcionan el escalado y los modos de capacidad, y patrones prácticos para enviar cambios a una arquitectura dirigida por eventos.
DynamoDB se organiza alrededor de unos bloques sencillos, pero los detalles importan porque determinan cómo modelas los datos y la rapidez (y coste) de las solicitudes.
Una tabla es el contenedor de más alto nivel. Cada registro en una tabla es un item (similar a una fila), y cada item es un conjunto de atributos (similar a columnas).
A diferencia de las bases relacionales, los items en la misma tabla no necesitan compartir los mismos atributos. Un item puede tener {status, total, customerId}, mientras que otro incluye {status, shipmentTracking}—DynamoDB no exige un esquema fijo.
Cada item se identifica de forma única por una clave primaria, y DynamoDB soporta dos tipos:
En la práctica, las claves compuestas permiten patrones “agrupados” como “todas las órdenes de un cliente, más recientes primero”.
Un Query lee items por clave primaria (o por la clave de un índice). Se dirige a una clave de partición específica y puede filtrar por rangos de la clave de ordenación—esta es la vía eficiente y preferida.
Un Scan recorre toda la tabla (o índice) y luego filtra. Es fácil de empezar, pero suele ser más lento y costoso a escala.
Algunas restricciones que notarás pronto:
Estos fundamentos preparan todo lo que sigue: patrones de acceso, elección de índices y características de rendimiento.
DynamoDB suele describirse tanto como un almacén clave-valor como una base de datos document. Eso es correcto, pero ayuda entender qué implica cada enfoque en el diseño diario.
En esencia, recuperas datos por clave. Proporciona los valores de la clave primaria y DynamoDB devuelve un único item. Esa consulta por clave es lo que aporta almacenamiento de latencia baja y predecible para muchas cargas.
Al mismo tiempo, un item puede contener atributos anidados (maps y lists), lo que lo hace sentir como una base de datos de documentos: puedes guardar cargas estructuradas sin definir un esquema rígido de antemano.
Los items encajan de forma natural con datos tipo JSON:
profile.name, profile.address).Esto es ideal cuando una entidad suele leerse completa—como un perfil de usuario, un carrito de la compra o un paquete de configuración.
DynamoDB no soporta joins en servidor. Si tu app necesita obtener “un pedido más sus líneas de pedido y el estado de envío” en una ruta de lectura, a menudo desnormalizarás: copiar algunos atributos en varios items o incrustar pequeñas subestructuras dentro de un item.
La desnormalización incrementa la complejidad de escritura y puede provocar fan-out de actualizaciones. La recompensa son menos viajes de ida y vuelta y lecturas más rápidas—a menudo, el camino crítico en sistemas escalables.
Las consultas más rápidas en DynamoDB son las que puedes expresar como “dame esta partición” (y opcionalmente “dentro de esta partición, dame este rango”). Por eso la elección de la clave se trata principalmente de cómo lees los datos, no solo de cómo los almacenas.
La clave de partición determina qué partición física almacena un item. DynamoDB hace un hash de este valor para repartir datos y tráfico. Si muchas solicitudes se concentran en un pequeño conjunto de valores de clave de partición, puedes crear particiones “calientes” y alcanzar límites de throughput aunque la tabla esté en general inactiva.
Buenas claves de partición:
"GLOBAL")Con una clave de ordenación, los items que comparten la misma clave de partición se almacenan juntos y se ordenan por la clave de ordenación. Esto habilita eficientemente:
BETWEEN, begins_with)Un patrón común es componer la clave de ordenación, como TYPE#id o TS#2025-12-22T10:00:00Z, para soportar múltiples formas de consulta sin tablas extra.
PK = USER#<id> (simple GetItem)PK = USER#<id>, SK begins_with ORDER# (o SK = CREATED_AT#...)PK = DEVICE#<id>, SK = TS#<timestamp> con BETWEEN para ventanas de tiempoSi tu clave de partición se alinea con tus consultas de mayor volumen y distribuye uniformemente, obtendrás lecturas y escrituras con latencia baja y consistente. Si no, compensarás con scans, filtros o índices extra—cada uno aumentando coste y riesgo de claves calientes.
Los índices secundarios ofrecen rutas de consulta alternativas fuera de la clave primaria de la tabla. En lugar de remodelar la tabla base cada vez que aparece un nuevo patrón de acceso, puedes añadir un índice que re-keys los mismos items para una consulta diferente.
Un Global Secondary Index (GSI) tiene su propia clave de partición (y opcionalmente clave de ordenación) que puede ser completamente distinta de la de la tabla. Es “global” porque abarca todas las particiones de la tabla y puede añadirse o eliminarse en cualquier momento. Usa un GSI cuando necesites un patrón de acceso nuevo que no encaje con la clave original—por ejemplo, consultar pedidos por customerId cuando la tabla está indexada por orderId.
Un Local Secondary Index (LSI) comparte la misma clave de partición que la tabla base pero usa una clave de ordenación diferente. Los LSI deben definirse al crear la tabla. Son útiles cuando quieres múltiples órdenes dentro del mismo grupo de entidad (misma clave de partición), como recuperar las órdenes de un cliente ordenadas por createdAt vs. status.
La proyección determina qué atributos DynamoDB almacena en el índice:
Cada escritura en la tabla base puede desencadenar escrituras en uno o varios índices. Más GSIs y proyecciones amplias aumentan el coste y el consumo de capacidad. Planifica los índices en torno a patrones de acceso estables y mantiene las proyecciones lo más ajustadas posible.
El escalado en DynamoDB comienza con una elección: On-Demand o Provisioned. Ambos pueden alcanzar un throughput muy alto, pero se comportan de forma diferente ante cambios en el tráfico.
On-Demand es lo más sencillo: pagas por petición y DynamoDB se adapta automáticamente a cargas variables. Es ideal para tráfico impredecible, productos en etapas iniciales y cargas con picos donde no quieres gestionar objetivos de capacidad.
Provisioned es planificación de capacidad: especificas (o autoescalas) throughput de lectura/escritura y obtienes precios más predecibles con uso constante. Suele ser más barato para cargas conocidas y equipos que pueden prever la demanda.
El throughput provisionado se mide en:
El tamaño real del item y el patrón de acceso determinan el coste real: items más grandes, consistencia fuerte y scans pueden consumir capacidad rápidamente.
El autoescalado ajusta RCUs/WCUs provisionadas según objetivos de utilización. Ayuda con crecimiento gradual y ciclos previsibles, pero no es instantáneo. Los picos repentinos aún pueden provocar throttling si la capacidad no sube lo bastante rápido, y no soluciona una clave de partición caliente que concentre tráfico en una partición.
DynamoDB Accelerator (DAX) es una caché en memoria que puede reducir latencia de lectura y descargar lecturas repetidas (por ejemplo, páginas de producto populares, sesiones, tablas de clasificación). Es más útil cuando muchos clientes solicitan repetidamente los mismos items; no ayuda patrones dominados por escrituras y no sustituye un buen diseño de claves.
DynamoDB permite intercambiar garantías de lectura contra latencia y coste, así que es importante ser explícito sobre qué significa “correcto” en cada operación.
Por defecto, GetItem y Query usan lecturas eventualmente consistentes: podrías ver brevemente un valor antiguo justo después de una escritura. Esto suele ser aceptable para feeds, catálogos de producto y otras vistas con muchas lecturas.
Con lecturas fuertemente consistentes (opción para lecturas desde la tabla base en una sola región), DynamoDB garantiza que ves la última escritura confirmada. La consistencia fuerte cuesta más en capacidad de lectura y puede aumentar la latencia en cola, así que úsala para lecturas realmente críticas.
La consistencia fuerte es valiosa para lecturas que condicionan acciones irreversibles:
Para contadores, el enfoque más seguro suele ser una actualización atómica (por ejemplo, UpdateItem con ADD) para que los incrementos no se pierdan.
Las transacciones de DynamoDB (TransactWriteItems, TransactGetItems) proporcionan semántica ACID sobre hasta 25 items. Son útiles cuando debes actualizar múltiples items juntos—como escribir un pedido y reservar inventario—o hacer cumplir invariantes que no toleran estados intermedios.
Los reintentos son normales en sistemas distribuidos. Haz las escrituras idempotentes para que los reintentos no dupliquen efectos:
ConditionExpression (por ejemplo, “solo crear si attribute_not_exists”)La corrección en DynamoDB es, en gran parte, seleccionar el nivel de consistencia adecuado y diseñar operaciones para que los reintentos no dañen los datos.
DynamoDB almacena datos de la tabla en múltiples particiones físicas. Cada partición tiene throughput finito para lecturas y escrituras, además de un límite en cuánto dato puede contener. Tu clave de partición determina dónde vive un item; si demasiadas solicitudes apuntan al mismo valor (o a pocos valores), esa partición se convierte en cuello de botella.
Las particiones calientes suelen deberse a elecciones de clave que concentran tráfico: una clave de partición “global” como USER#1, TENANT#default o STATUS#OPEN, o patrones ordenados por tiempo donde todo escribe en “ahora” bajo una misma clave.
Normalmente verás:
ProvisionedThroughputExceededException) para un subconjunto de clavesDiseña para distribución primero, luego para conveniencia de consulta:
TENANT#<id> en lugar de una constante compartida).ORDER#<id>#<shard> para repartir escrituras entre N shards, y luego consulta entre shards cuando sea necesario.METRIC#2025-12-22T10) para evitar que “todas las escrituras vayan al item más reciente”.Para picos impredecibles, la capacidad on-demand puede absorber ráfagas (dentro de los límites del servicio). Con capacidad provisionada, usa auto scaling e implementa backoff exponencial con jitter en el cliente para evitar reintentos sincronizados que amplifiquen el pico.
El modelado en DynamoDB parte de los patrones de acceso, no de diagramas ER. Diseñas claves para que las consultas que necesitas sean rápidas Query, mientras que el resto se evita o se maneja de forma asíncrona.
“El diseño de tabla única” significa almacenar múltiples tipos de entidad (usuarios, pedidos, mensajes) en una sola tabla y usar convenciones de clave consistentes para recuperar datos relacionados en una sola Query. Esto reduce viajes entre entidades y mantiene la latencia predecible.
Un enfoque común son las claves compuestas:
PK agrupa una partición lógica (por ejemplo, USER#123)SK ordena los items dentro de ese grupo (por ejemplo, PROFILE, ORDER#2025-12-01, MSG#000123)Esto te permite recuperar “todo para un usuario” o “solo las órdenes de un usuario” eligiendo un prefijo de la clave de ordenación.
Para relaciones tipo grafo, una lista de adyacencia funciona bien: almacena aristas como items.
PK = USER#123, SK = FOLLOWS#USER#456Para soportar búsquedas inversas o verdaderos muchos-a-muchos, añade un item de arista invertida o proyecta a un GSI, según los caminos de lectura.
Para eventos y métricas, evita particiones sin límite usando bucketing:
PK = DEVICE#9#2025-12-22 (device + día)SK = TS#1734825600 (timestamp)Usa TTL para expirar puntos antiguos automáticamente y guarda agregados (horarios/diarios) como items separados para dashboards rápidos.
Si quieres un repaso más profundo sobre convenciones de clave, consulta /blog/partition-key-and-sort-key-design.
DynamoDB Streams es la captura de cambios (CDC) integrada de DynamoDB. Cuando se activa en una tabla, cada insert, update o delete produce un registro de stream que los consumidores downstream pueden procesar—sin tener que sondear la tabla.
Un registro de stream contiene claves y (opcionalmente) la imagen antigua y/o nueva del item, según el stream view type que elijas (solo claves, imagen nueva, imagen antigua, ambas). Los registros se agrupan en shards, que se leen secuencialmente.
Una configuración común es DynamoDB Streams → AWS Lambda, donde cada lote de registros desencadena una función. También pueden existir consumidores personalizados (o canalizar a sistemas de analítica/log).
Flujos típicos incluyen:
Esto mantiene la tabla primaria optimizada para lecturas/escrituras de baja latencia mientras desplaza trabajo derivado a consumidores asíncronos.
Streams ofrecen procesamiento ordenado por shard (que suele correlacionarse con la clave de partición), pero no hay orden global entre todas las claves. La entrega es al menos una vez, por lo que pueden producirse duplicados.
Para manejarlo con seguridad:
Con estas garantías en mente, Streams puede convertir a DynamoDB en una columna vertebral sólida para sistemas orientados a eventos.
DynamoDB está diseñado para alta disponibilidad distribuyendo datos entre varias AZs dentro de una región. Para la mayoría de equipos, las ventajas prácticas de fiabilidad provienen de una estrategia clara de backups, entender las opciones de replicación y monitorizar las métricas correctas.
Los backups on-demand son snapshots manuales (o automatizados) que tomas cuando quieres un punto de restauración conocido—antes de una migración, después de un release o previo a un gran backfill. Son ideales para momentos “marcadores”.
Point-in-time recovery (PITR) captura cambios de forma continua para que puedas restaurar la tabla a cualquier segundo dentro de la ventana de retención. PITR es la red de seguridad para borrados accidentales, despliegues defectuosos o escrituras malformadas que pasaron validación.
Si necesitas resiliencia multi-región o lecturas de baja latencia cerca de usuarios, Global Tables replican datos entre regiones seleccionadas. Simplifican la planificación de failover, pero introducen retraso de replicación entre regiones y consideraciones de resolución de conflictos—mantén claros patrones de escritura y propiedad de items.
Como mínimo, alerta sobre:
Estas señales suelen revelar problemas de particiones calientes, capacidad insuficiente o patrones de acceso inesperados.
Para throttling, primero identifica el patrón de acceso que lo causa, luego mitiga cambiando temporalmente a on-demand o incrementando capacidad provisionada, y considera sharding de claves calientes.
Para fallos parciales o errores elevados, reduce el blast radius: desactiva tráfico no crítico, reintenta con backoff y jitter, y degrada con gracia (por ejemplo, sirviendo lecturas cacheadas) hasta que la tabla se estabilice.
La seguridad en DynamoDB trata sobre restringir quién puede invocar qué acciones API, desde dónde y sobre qué claves. Dado que las tablas pueden contener muchos tipos de entidad (y a veces múltiples tenants), el control de acceso debe diseñarse junto al modelo de datos.
Comienza con políticas IAM basadas en identidad que limiten acciones (por ejemplo, dynamodb:GetItem, Query, PutItem) al conjunto mínimo y acótalas a ARNs de tabla específicos.
Para control más fino, usa dynamodb:LeadingKeys para restringir acceso por valores de clave de partición—útil cuando un servicio o tenant solo debe leer/escribir en su propio espacio de claves.
DynamoDB cifra datos en reposo por defecto usando claves administradas por AWS o por el cliente (KMS). Si tienes requisitos de cumplimiento, verifica:
Para cifrado en tránsito, asegura que los clientes usen HTTPS (los SDKs de AWS lo hacen por defecto). Si terminas TLS en un proxy, confirma que el salto entre el proxy y DynamoDB siga cifrado.
Usa un VPC Gateway Endpoint para DynamoDB para mantener el tráfico en la red de AWS y aplicar políticas de endpoint que limiten el acceso. Combínalo con controles de egress (NACLs, security groups y routing) para evitar rutas que permitan acceso libre a Internet.
Para tablas compartidas, incluye un identificador de tenant en la clave de partición (por ejemplo, TENANT#<id>) y aplica aislamiento de tenant con condiciones IAM sobre dynamodb:LeadingKeys.
Si necesitas aislamiento más fuerte, considera tablas separadas por tenant o por entorno, y reserva diseños de tabla compartida para casos donde la simplicidad operativa y la eficiencia de costes compensen un blast radius mayor.
DynamoDB suele ser “barato cuando eres preciso, caro cuando eres vago.” Los costes siguen tus patrones de acceso, por lo que la mejor optimización comienza por hacer explícitos esos patrones.
Tu factura se moldea principalmente por:
Una sorpresa común: cada escritura en la tabla también es una escritura en cada GSI afectado, así que “solo un índice más” puede multiplicar el coste de escritura.
Un buen diseño de claves reduce la necesidad de operaciones costosas. Si frecuentemente usas Scan, estás pagando por leer datos que vas a descartar.
Prefiere:
Query por clave de partición (y opcionalmente condiciones sobre la clave de ordenación)Si un patrón de acceso es raro, considera servirlo mediante una tabla separada, un job ETL o un modelo de lectura cacheado en lugar de un GSI permanente.
Usa TTL para eliminar automáticamente items de corta vida (sesiones, tokens temporales, estado intermedio de workflows). Esto reduce almacenamiento y mantiene índices más pequeños con el tiempo.
Para datos append-heavy (eventos, logs), combina TTL con diseños de clave de ordenación que permitan consultar “solo lo reciente”, para no tocar historia fría rutinariamente.
En modo provisionado, establece bases conservadoras y escala con auto scaling según métricas reales. En on-demand, vigila patrones ineficientes (items grandes, clientes chatty) que eleven el volumen de peticiones.
Trata Scan como último recurso—cuando realmente necesites procesar toda la tabla, ejecútalo fuera de horas pico o como un batch controlado con paginación y backoff.
DynamoDB brilla cuando tu aplicación puede expresarse como un conjunto de patrones de acceso bien definidos y necesitas latencia baja y consistente a gran escala. Si puedes describir tus lecturas y escrituras por adelantado (por clave de partición, clave de ordenación y unos pocos índices), suele ser una forma simple de operar un almacén de datos altamente disponible.
DynamoDB es una opción sólida cuando tienes:
Busca otras opciones si tus requisitos principales incluyen:
Muchos equipos mantienen DynamoDB para lecturas/escrituras “calientes” y añaden:
Si validas patrones de acceso y convenciones de tabla única, la velocidad importa. Algunos equipos prototipan el servicio y la UI en Koder.ai (una plataforma que genera apps web, servidor y móviles desde chat) y luego iteran el diseño de claves de DynamoDB conforme emergen rutas de consulta reales. Incluso si el backend de producción difiere, prototipos E2E rápidos revelan qué consultas deben ser Query y cuáles se convertirían accidentalmente en Scan costosos.
Valida: (1) tus consultas principales son conocidas y basadas en claves, (2) las necesidades de corrección coinciden con el modelo de consistencia, (3) los tamaños de items y el crecimiento esperado están entendidos, y (4) el modelo de costes (on-demand vs provisionado más autoscaling) encaja en tu presupuesto.
DynamoDB es una base de datos NoSQL totalmente gestionada en AWS diseñada para lecturas/escrituras con latencia consistentemente baja a gran escala. Los equipos la usan cuando pueden definir patrones de acceso basados en claves (buscar por ID, listar por propietario, consultas por rangos de tiempo) y quieren evitar gestionar la infraestructura de base de datos.
Es especialmente común en microservicios, aplicaciones serverless y sistemas orientados a eventos.
Una tabla contiene items (como filas). Cada item es un conjunto flexible de atributos (como columnas) y puede incluir datos anidados.
DynamoDB funciona bien cuando una petición normalmente necesita “la entidad completa”, porque los items pueden contener maps y lists (estructuras tipo JSON).
Una clave de partición por sí sola identifica unívocamente un item (clave primaria simple). Una clave de partición + clave de ordenación (clave compuesta) permite que varios items compartan la misma clave de partición a la vez que permanecen identificables y ordenados por la clave de ordenación.
Las claves compuestas permiten patrones como:
Usa Query cuando puedas especificar la clave de partición (y opcionalmente una condición sobre la clave de ordenación). Es la vía rápida y escalable.
Usa Scan solo cuando realmente necesites leer todo; recorre toda la tabla o índice y filtra después, lo que suele ser más lento y costoso.
Si haces scans con frecuencia, es señal de que el diseño de tu clave o índices necesita ajustarse.
Los índices secundarios ofrecen rutas de consulta alternativas.
Los índices aumentan el coste de escritura porque las escrituras se replican en el índice.
Elige On-Demand si el tráfico es impredecible, con picos, o no quieres gestionar capacidad. Pagas por petición.
Elige Provisioned si el uso es estable/predictible y quieres costes más controlados. Combínalo con auto scaling, pero recuerda que puede no reaccionar instantáneamente a picos súbitos.
Por defecto, las lecturas son eventualmente consistentes, lo que significa que justo después de una escritura puedes leer un valor antiguo.
Usa lecturas fuertemente consistentes (cuando estén disponibles) para comprobaciones críticas que deben estar actualizadas, como puertas de autorización o transiciones de estado de workflows.
Para corrección bajo concurrencia, prefiere actualizaciones atómicas (por ejemplo, escrituras condicionales o ADD) sobre bucles de leer-modificar-escribir.
Las transacciones (TransactWriteItems, TransactGetItems) ofrecen garantías ACID para hasta 25 items.
Úsalas cuando debas actualizar varios items juntos (por ejemplo, crear un pedido y reservar inventario) o hacer cumplir invariantes que no toleran estados intermedios.
Cuestan más y añaden latencia, así que resérvalas para los flujos que realmente las requieren.
Las particiones calientes ocurren cuando demasiadas peticiones apuntan al mismo valor de clave de partición (o a un pequeño conjunto), provocando throttling aunque la tabla esté, en general, infrautilizada.
Mitigaciones comunes:
Activa DynamoDB Streams para obtener un feed de cambios (inserciones, actualizaciones, eliminaciones). Un patrón común es Streams → Lambda para activar trabajo downstream.
Garantías importantes a considerar:
Haz que los consumidores sean (upsert por clave, escrituras condicionales o registro de IDs de eventos procesados).