· nervico-team · arquitectura-cloud · 10 min read
Bases de datos en AWS: RDS, Aurora y DynamoDB comparados
Comparativa técnica entre RDS, Aurora y DynamoDB en AWS: rendimiento, costes reales, patrones de uso, limitaciones y criterios claros para elegir la base de datos correcta.
AWS ofrece 15 servicios de bases de datos diferentes. Pero para el 90% de las aplicaciones, la decisión se reduce a tres: RDS, Aurora y DynamoDB. Cada uno sirve a un caso de uso distinto, y elegir el incorrecto cuesta dinero, rendimiento y tiempo de ingeniería.
RDS es la opción conservadora: bases de datos relacionales gestionadas con motores familiares. Aurora es la evolución de RDS: compatible con MySQL y PostgreSQL pero con un motor de almacenamiento rediseñado por AWS. DynamoDB es la opción NoSQL: latencia de milisegundos a cualquier escala, pero con un modelo de datos que exige pensar diferente.
Este artículo compara los tres servicios con datos verificados, costes reales y escenarios concretos. No hay una base de datos universalmente mejor. Hay una base de datos correcta para cada problema.
RDS: bases de datos relacionales gestionadas
Qué es RDS
RDS (Relational Database Service) es un servicio gestionado que ejecuta motores de bases de datos relacionales estándar en la infraestructura de AWS. AWS gestiona el aprovisionamiento, los parches del sistema operativo, los backups y la replicación. Tu equipo gestiona el esquema, las consultas y la optimización.
Motores disponibles:
- PostgreSQL: Versiones 12 a 16. El motor más versátil para aplicaciones generales.
- MySQL: Versiones 5.7 y 8.0. El motor más popular del mundo.
- MariaDB: Versiones 10.5 a 10.11. Fork de MySQL con mejoras en rendimiento.
- Oracle: Standard Edition y Enterprise Edition. Para aplicaciones legacy que requieren Oracle.
- SQL Server: Express, Web, Standard y Enterprise. Para ecosistemas Microsoft.
Cómo funciona internamente
RDS ejecuta la base de datos en instancias EC2 dedicadas con almacenamiento EBS. Pero no tienes acceso SSH a la instancia: AWS gestiona el sistema operativo y el motor de base de datos. Tu punto de acceso es el endpoint de conexión (host:puerto).
Almacenamiento: RDS usa volúmenes EBS con tres opciones:
| Tipo | IOPS | Uso recomendado | Coste (eu-west-1) |
|---|---|---|---|
| gp3 | 3.000 base + hasta 16.000 | Cargas generales | 0,0952 $/GB/mes |
| io2 | Hasta 256.000 | Cargas intensivas en I/O | 0,131 $/GB/mes + 0,066 $/IOPS |
| Magnetic | Variable | Solo legacy, no usar | 0,116 $/GB/mes |
Recomendación: gp3 para el 95% de los casos. io2 solo si necesitas más de 16.000 IOPS consistentes.
Alta disponibilidad con Multi-AZ
Multi-AZ crea una réplica síncrona de tu base de datos en otra zona de disponibilidad. Si la instancia principal falla, AWS realiza un failover automático en 60-120 segundos. El endpoint de conexión no cambia.
# Crear instancia RDS con Multi-AZ
aws rds create-db-instance \
--db-instance-identifier my-database \
--db-instance-class db.r6g.large \
--engine postgres \
--engine-version 16.1 \
--master-username admin \
--master-user-password "SecurePassword123!" \
--allocated-storage 100 \
--storage-type gp3 \
--multi-az \
--vpc-security-group-ids sg-12345678 \
--db-subnet-group-name my-subnet-group \
--backup-retention-period 7 \
--storage-encrypted \
--kms-key-id alias/rds-encryption-keyCoste de Multi-AZ: Duplica el coste de la instancia. Una db.r6g.large pasa de 0,252 dolares/hora a 0,504 dolares/hora. No es barato, pero para producción es obligatorio.
Read Replicas para lectura escalable
Si tu aplicación es intensiva en lectura (dashboards, reportes, consultas analíticas), puedes crear hasta 15 Read Replicas. Las réplicas son asíncronas: hay un retraso (lag) de milisegundos a segundos entre la escritura en la primaria y la disponibilidad en la réplica.
# Terraform: Read Replica
resource "aws_db_instance" "read_replica" {
replicate_source_db = aws_db_instance.primary.identifier
instance_class = "db.r6g.large"
publicly_accessible = false
tags = {
Name = "read-replica-1"
Role = "read"
}
}Patrón de uso: La aplicación envía escrituras a la instancia primaria y lecturas a las réplicas. Los frameworks ORM como SQLAlchemy, Sequelize o TypeORM soportan esta configuración nativamente.
Costes de RDS
| Instancia | vCPU | RAM | Coste On-Demand (eu-west-1) | Coste Reserved 1 año |
|---|---|---|---|---|
| db.t4g.micro | 2 | 1 GB | 12,41 $/mes | 8,03 $/mes |
| db.t4g.medium | 2 | 4 GB | 49,64 $/mes | 32,12 $/mes |
| db.r6g.large | 2 | 16 GB | 183,96 $/mes | 116,07 $/mes |
| db.r6g.xlarge | 4 | 32 GB | 367,92 $/mes | 232,14 $/mes |
| db.r6g.2xlarge | 8 | 64 GB | 735,84 $/mes | 464,28 $/mes |
Aurora: el motor rediseñado por AWS
Qué diferencia a Aurora de RDS
Aurora es compatible con MySQL 8.0 y PostgreSQL (versiones 13-16), pero usa un motor de almacenamiento completamente diferente al de RDS. En lugar de escribir datos en un volumen EBS local, Aurora escribe en un sistema de almacenamiento distribuido que replica los datos 6 veces en 3 zonas de disponibilidad.
Instancia primaria → Storage Layer (6 copias en 3 AZs)
↑
Read Replicas (hasta 15) ─┘Implicaciones prácticas:
- Failover más rápido: Aurora realiza failover en menos de 30 segundos (vs 60-120 en RDS Multi-AZ).
- Read Replicas sin lag: Las réplicas de Aurora leen del mismo storage layer que la primaria. El lag es de milisegundos, no de segundos.
- Almacenamiento autoexpansible: Empieza en 10 GB y crece automáticamente hasta 128 TB. No necesitas predimensionar.
- Backups continuos: Aurora hace backup continuo a S3 sin impacto en rendimiento.
Aurora Serverless v2
Aurora Serverless v2 escala automáticamente la capacidad de compute en incrementos de 0,5 ACU (Aurora Capacity Units). Un ACU equivale aproximadamente a 2 GB de RAM.
# Terraform: Aurora Serverless v2
resource "aws_rds_cluster" "aurora_serverless" {
cluster_identifier = "my-aurora-cluster"
engine = "aurora-postgresql"
engine_mode = "provisioned"
engine_version = "16.1"
database_name = "myapp"
master_username = "admin"
master_password = "SecurePassword123!"
storage_encrypted = true
serverlessv2_scaling_configuration {
min_capacity = 0.5
max_capacity = 16
}
}
resource "aws_rds_cluster_instance" "serverless" {
cluster_identifier = aws_rds_cluster.aurora_serverless.id
instance_class = "db.serverless"
engine = aws_rds_cluster.aurora_serverless.engine
engine_version = aws_rds_cluster.aurora_serverless.engine_version
}Cuándo usar Serverless v2: Cargas de trabajo impredecibles. Si tu aplicación tiene picos de tráfico seguidos de períodos de baja actividad, Serverless v2 escala automáticamente y pagas solo por la capacidad consumida.
Cuándo no usarlo: Cargas de trabajo constantes. Si tu base de datos usa 8 ACUs las 24 horas del día, una instancia provisioned (db.r6g.xlarge) es significativamente más barata.
Aurora vs RDS: comparativa directa
| Característica | RDS PostgreSQL | Aurora PostgreSQL |
|---|---|---|
| Almacenamiento | EBS (gp3 o io2) | Distribuido, 6 copias en 3 AZs |
| Máximo almacenamiento | 64 TB | 128 TB |
| Read Replicas | 15 (async, lag de segundos) | 15 (mismo storage, lag de ms) |
| Failover | 60-120 segundos | Menos de 30 segundos |
| Backup | Snapshots diarios | Continuo a S3 |
| Escalado de storage | Manual (redimensionar EBS) | Automático |
| Coste (db.r6g.large equiv.) | 183,96 $/mes | 219,00 $/mes |
| Coste de almacenamiento | 0,0952 $/GB/mes (gp3) | 0,10 $/GB/mes |
| Coste de I/O | Incluido en gp3 | 0,20 $ por millón de peticiones |
Veredicto: Aurora cuesta un 15-20% más que RDS para cargas equivalentes, pero la diferencia se justifica cuando necesitas failover rápido, read replicas sin lag o almacenamiento que escala automáticamente. Para aplicaciones que pueden tolerar failovers de 2 minutos y lag de replicación de segundos, RDS es la opción más económica.
DynamoDB: NoSQL para escala extrema
Modelo de datos
DynamoDB no es una base de datos relacional. No tiene tablas con esquema fijo, no soporta JOINs y no usa SQL. Es una base de datos key-value y document store que ofrece latencia de milisegundos de un dígito a cualquier escala.
Conceptos fundamentales:
- Table: La unidad organizativa. Equivale conceptualmente a una tabla relacional, pero sin esquema fijo.
- Item: Un registro en la tabla. Equivale a una fila. Cada item puede tener atributos diferentes.
- Partition Key (PK): El atributo que DynamoDB usa para distribuir datos. Determina en qué partición física se almacena cada item.
- Sort Key (SK): Atributo opcional que, combinado con PK, permite almacenar múltiples items con la misma PK ordenados por SK.
- GSI (Global Secondary Index): Un índice que permite consultar la tabla por un atributo diferente al PK/SK original.
Diseño de tabla: la mentalidad correcta
En una base de datos relacional, el diseño sigue este proceso:
- Identificar entidades (Users, Orders, Products)
- Normalizar (3NF)
- Crear tablas y relaciones
- Escribir consultas cuando las necesites
En DynamoDB, el proceso es inverso:
- Identificar todos los patrones de acceso (queries que tu aplicación necesita)
- Diseñar la tabla para soportar esos patrones
- Desnormalizar agresivamente
Patrones de acceso ejemplo:
1. Obtener usuario por ID
2. Obtener todos los pedidos de un usuario
3. Obtener pedido por ID
4. Obtener pedidos de un usuario en un rango de fechas
5. Obtener productos más vendidos
Diseño de tabla:
PK | SK | Atributos
------------------|----------------------|------------------
USER#u001 | PROFILE | name, email, plan
USER#u001 | ORDER#2024-01-15#o01 | total, status
USER#u001 | ORDER#2024-02-20#o02 | total, status
ORDER#o01 | METADATA | user_id, items, total
PRODUCT#p001 | METADATA | name, price, sales_countModos de capacidad
On-Demand: Pagas por lectura y escritura realizadas. Sin necesidad de planificar capacidad.
- Lectura: 0,25 dolares por millón de unidades de lectura
- Escritura: 1,25 dolares por millón de unidades de escritura
- Ideal para cargas impredecibles o nuevas aplicaciones
Provisioned: Defines las unidades de capacidad que necesitas. Más barato para cargas predecibles.
- Lectura: 0,00013 dolares por RCU por hora
- Escritura: 0,00065 dolares por WCU por hora
- Auto Scaling ajusta la capacidad automáticamente dentro de límites definidos
Comparativa de coste para 100 millones de lecturas y 20 millones de escrituras al mes:
| Modo | Coste de lectura | Coste de escritura | Total/mes |
|---|---|---|---|
| On-Demand | 25,00 $ | 25,00 $ | 50,00 $ |
| Provisioned (sin reserva) | 14,04 $ | 14,04 $ | 28,08 $ |
| Provisioned (Reserved 1 año) | 8,42 $ | 8,42 $ | 16,84 $ |
Global Tables: replicación multi-región
DynamoDB Global Tables replica datos entre regiones de AWS con consistencia eventual. Cada región es activa para lectura y escritura (active-active).
# Crear tabla con replicación global
aws dynamodb create-table \
--table-name MyGlobalTable \
--attribute-definitions \
AttributeName=pk,AttributeType=S \
AttributeName=sk,AttributeType=S \
--key-schema \
AttributeName=pk,KeyType=HASH \
AttributeName=sk,KeyType=RANGE \
--billing-mode PAY_PER_REQUEST \
--region eu-west-1
# Añadir réplica en us-east-1
aws dynamodb update-table \
--table-name MyGlobalTable \
--replica-updates \
'[{"Create": {"RegionName": "us-east-1"}}]' \
--region eu-west-1Coste adicional: Las escrituras replicadas se facturan como escrituras adicionales en cada región destino. Si escribes 1 millón de items en eu-west-1 y tienes una réplica en us-east-1, pagas 1 millón de escrituras en cada región.
Cuándo usar cada servicio
Usa RDS cuando
- Tu aplicación necesita consultas SQL complejas con JOINs
- El equipo tiene experiencia con bases de datos relacionales y no hay tiempo para aprender DynamoDB
- Los patrones de acceso no están claros y pueden cambiar (SQL es flexible)
- Necesitas transacciones ACID estándar
- El volumen de datos es menor a 1 TB y el tráfico es predecible
Usa Aurora cuando
- Todo lo anterior aplica, pero además necesitas failover rápido y read replicas sin lag
- El volumen de datos puede crecer significativamente (hasta 128 TB)
- Tienes cargas de lectura intensivas que requieren múltiples réplicas
- Quieres aprovechar Aurora Serverless v2 para cargas variables
Usa DynamoDB cuando
- Necesitas latencia de milisegundos de un dígito a cualquier escala
- Los patrones de acceso están bien definidos y son estables
- El volumen de datos crece continuamente (logs, eventos, IoT)
- Necesitas replicación global multi-región (Global Tables)
- Tu arquitectura es serverless (Lambda se integra nativamente con DynamoDB)
No uses DynamoDB cuando
- Necesitas consultas ad-hoc frecuentes (reportes, análisis exploratorio)
- Los patrones de acceso cambian con frecuencia
- Necesitas JOINs complejos entre entidades
- Tu equipo no tiene experiencia con modelado NoSQL y no hay tiempo para aprenderlo
Combinaciones que funcionan
La decisión no siempre es excluyente. Muchas arquitecturas combinan servicios:
Aurora para datos transaccionales + DynamoDB para sesiones y caché:
Usuario → API → Aurora (pedidos, usuarios, productos)
DynamoDB (sesiones, carrito, preferencias)RDS para la aplicación principal + DynamoDB para eventos y logs:
Aplicación → RDS (datos del negocio)
→ DynamoDB (audit log, eventos, actividad)Aurora como base principal + ElastiCache para consultas frecuentes:
Aplicación → ElastiCache (Redis) → Cache hit: respuesta inmediata
→ Cache miss: consulta AuroraErrores frecuentes
Error 1: elegir DynamoDB por moda
DynamoDB es una herramienta de ingeniería, no una tendencia. Si tu aplicación tiene patrones de acceso impredecibles y necesita consultas flexibles, PostgreSQL en RDS o Aurora es la opción correcta. Hemos visto equipos que eligen DynamoDB para un CRUD simple y terminan construyendo un ORM casero que reimplementa mal lo que PostgreSQL hace de forma nativa.
Error 2: no activar Multi-AZ en producción
Una instancia RDS single-AZ tiene un SLA de disponibilidad del 99.5% (43 horas de downtime potencial al año). Con Multi-AZ, el SLA sube al 99.95% (4,38 horas). La diferencia de coste es 2x. La diferencia en impacto de negocio cuando tu base de datos cae en horario pico es incalculable.
Error 3: no monitorizar el lag de replicación
Si tu aplicación lee de Read Replicas y asume que los datos están actualizados, un lag de replicación de 5 segundos puede causar inconsistencias visibles para el usuario. Monitoriza el lag con CloudWatch y configura alertas si supera los 100ms.
Error 4: sobredimensionar DynamoDB en modo Provisioned
Si provisionas 10.000 WCU pero usas 500, estás pagando 20 veces más de lo necesario. Usa Auto Scaling con límites razonables o empieza con On-Demand hasta que entiendas tus patrones de tráfico.
Conclusión
No existe una base de datos universal en AWS. RDS es la opción segura para equipos con experiencia relacional y aplicaciones con patrones de acceso flexibles. Aurora es RDS mejorado, justificado cuando necesitas failover rápido, read replicas sin lag o almacenamiento que escale automáticamente. DynamoDB es la opción para escala extrema, latencia garantizada y arquitecturas serverless, pero exige un diseño de datos riguroso que no permite cambios fáciles después.
La decisión correcta depende de tus patrones de acceso, tu volumen de datos, tu presupuesto y la experiencia de tu equipo. Si no estás seguro de cuál elegir, empieza con PostgreSQL en RDS. Es la opción más flexible y la que menos te penaliza si necesitas cambiar de dirección.
Si necesitas ayuda para diseñar tu capa de datos en AWS, nuestro equipo de consultoría ha implementado estas arquitecturas en productos reales con millones de registros. Solicita una auditoría gratuita para evaluar tu arquitectura de datos actual.