Start from the data, not the service
| Question | Leads towards |
|---|---|
| Relational model, joins, transactions, ad-hoc queries? | RDS / Aurora |
| Key-value or simple document access by known keys at any scale? | DynamoDB |
| MongoDB-compatible documents? | DocumentDB (check compatibility with your driver/features) |
| Sub-millisecond cache in front of another store? | ElastiCache (Valkey/Redis OSS/Memcached) |
| In-memory primary database with durability? | MemoryDB |
| Commercial engine required by a vendor (Oracle, SQL Server, Db2)? | RDS for that engine (or EC2 if RDS doesn't support required features) |
RDS or Aurora?
| RDS (MySQL/PostgreSQL) | Aurora (MySQL/PostgreSQL-compatible) | |
|---|---|---|
| Storage | EBS volumes per instance | Shared distributed storage across 3 AZs |
| HA | Multi-AZ instance (standby) or Multi-AZ cluster (readable standbys) | Readers in other AZs, fast failover |
| Read scaling | Read replicas (async) | Up to many readers on shared storage, low lag |
| DR | Cross-region read replicas, snapshots | Global Database (fast cross-region) |
| Variable load | Fixed instance | Serverless v2 option |
| Cost shape | Usually lower for small/steady | Higher floor; better at scale and for read-heavy |
Small, steady databases often fit RDS. Business-critical, read-heavy or cross-region workloads often justify Aurora.
DynamoDB: when it shines
- Known access patterns, high scale, predictable single-digit-ms latency.
- Serverless operations: no instances, patching or failover to manage.
- Global tables for multi-region active-active.
It's a poor fit when the access patterns aren't known yet, for ad-hoc analytics, or for teams expecting relational behaviour. Design the partition key and access patterns up front (single-table design if the team is comfortable with it).
Decide with the database
| Topic | Decide |
|---|---|
| HA | Multi-AZ option; failover time the app can tolerate |
| DR | RPO/RTO → snapshots, cross-region replicas, Global Database, global tables |
| Network | Private subnets, security groups, RDS Proxy for Lambda/connection storms |
| Identity | IAM database authentication / Secrets Manager rotation |
| Encryption | KMS key choice (AWS managed vs customer managed) |
| Backups | Retention, AWS Backup policy, restore tests |
| Upgrades | Engine version lifecycle and Extended Support charges |
Design review questions
- What are the top five queries/access patterns, and does the choice serve them well?
- What does the application do during a failover (retries, DNS caching, connection pools)?
- Size in three years, and the service's limits at that size?
- Who tunes it and watches its capacity?
Tip
Polyglot persistence is fine (DynamoDB for sessions, Aurora for orders, ElastiCache for caching), but every extra engine needs skills, monitoring, backups and upgrades. Add one only when it clearly earns its keep.
Checklist
- Data model and access patterns written down
- Engine and service chosen with compatibility checked
- RDS vs Aurora decided with cost and resilience in view
- HA, DR, network, identity, encryption and backups designed
- Owner for tuning, capacity and upgrades