Skip to main content

RDS vs Aurora vs DynamoDB — Which AWS Database Should You Use?

· 6 min read
Goel Academy
DevOps & Cloud Learning Hub

"Should we use Aurora or DynamoDB?" I've heard this question in every architecture review I've attended. The answer is never simple, because the question is wrong. You don't pick a database engine first — you pick it based on your access patterns, consistency needs, and budget. Let's build a framework for making the right call.

The Decision Tree

Before comparing engines, answer these three questions:

  1. Do you need relationships between data? (JOINs, foreign keys, transactions across tables)

    • Yes: Go relational (RDS or Aurora)
    • No: Consider DynamoDB
  2. What's your read/write ratio?

    • Read-heavy with complex queries: RDS/Aurora
    • Write-heavy with simple key lookups: DynamoDB
  3. How much operational overhead can you tolerate?

    • Minimal: Aurora Serverless or DynamoDB
    • Standard: RDS with Multi-AZ

RDS Engines Compared

RDS supports six database engines. Here's how they stack up:

EngineVersionBest ForLicense CostNotes
PostgreSQLUp to 16.xGeneral purpose, GIS, JSONFreeMost feature-rich open-source option
MySQLUp to 8.xWeb applications, WordPressFreeLargest community, most tutorials
MariaDBUp to 10.xMySQL alternativeFreeBetter performance than MySQL in some cases
Oracle19c, 21cEnterprise legacy apps$$$ (or BYOL)Only if you're already committed
SQL Server2019, 2022.NET applications$$$ (included)License cost is significant
Db211.5Mainframe migrations$$$ (or BYOL)Niche use case

For new projects: PostgreSQL is the default choice. It's free, feature-rich, and AWS invests heavily in PostgreSQL-compatible Aurora.

# Create a PostgreSQL RDS instance
aws rds create-db-instance \
--db-instance-identifier my-app-db \
--db-instance-class db.t3.medium \
--engine postgres \
--engine-version 16.4 \
--master-username admin \
--master-user-password 'YourSecurePassword123!' \
--allocated-storage 100 \
--storage-type gp3 \
--vpc-security-group-ids sg-0abc123def456 \
--db-subnet-group-name my-db-subnet-group \
--multi-az \
--storage-encrypted \
--backup-retention-period 7 \
--deletion-protection \
--tags Key=Environment,Value=production

Aurora — The AWS Premium Option

Aurora is AWS's cloud-native database. It's compatible with MySQL and PostgreSQL but re-engineered from the ground up for the cloud. The key differences:

  • 3x MySQL throughput, 5x PostgreSQL throughput (AWS's claim, real-world varies)
  • Storage auto-scales from 10GB to 128TB with no downtime
  • 6-way replication across 3 AZs automatically
  • Up to 15 read replicas (RDS supports 5)
  • Automatic failover in under 30 seconds
# Create an Aurora PostgreSQL cluster
aws rds create-db-cluster \
--db-cluster-identifier my-aurora-cluster \
--engine aurora-postgresql \
--engine-version 16.4 \
--master-username admin \
--master-user-password 'YourSecurePassword123!' \
--vpc-security-group-ids sg-0abc123def456 \
--db-subnet-group-name my-db-subnet-group \
--storage-encrypted \
--backup-retention-period 14 \
--deletion-protection

# Add a writer instance
aws rds create-db-instance \
--db-instance-identifier my-aurora-writer \
--db-cluster-identifier my-aurora-cluster \
--engine aurora-postgresql \
--db-instance-class db.r6g.large

# Add a reader instance
aws rds create-db-instance \
--db-instance-identifier my-aurora-reader \
--db-cluster-identifier my-aurora-cluster \
--engine aurora-postgresql \
--db-instance-class db.r6g.large

Aurora Serverless v2 is worth considering for variable workloads — it scales compute up and down automatically:

# Create an Aurora Serverless v2 cluster
aws rds create-db-cluster \
--db-cluster-identifier my-serverless-cluster \
--engine aurora-postgresql \
--engine-version 16.4 \
--master-username admin \
--master-user-password 'YourSecurePassword123!' \
--serverless-v2-scaling-configuration MinCapacity=0.5,MaxCapacity=16 \
--vpc-security-group-ids sg-0abc123def456 \
--db-subnet-group-name my-db-subnet-group

DynamoDB — When You Don't Need SQL

DynamoDB is a fully managed NoSQL database for key-value and document data. It shines when your access patterns are well-defined and you don't need complex queries.

# Create a DynamoDB table
aws dynamodb create-table \
--table-name UserSessions \
--attribute-definitions \
AttributeName=UserId,AttributeType=S \
AttributeName=SessionId,AttributeType=S \
--key-schema \
AttributeName=UserId,KeyType=HASH \
AttributeName=SessionId,KeyType=RANGE \
--billing-mode PAY_PER_REQUEST \
--tags Key=Environment,Value=production

# Put an item
aws dynamodb put-item \
--table-name UserSessions \
--item '{
"UserId": {"S": "user-123"},
"SessionId": {"S": "sess-abc"},
"LoginTime": {"S": "2025-04-19T10:30:00Z"},
"TTL": {"N": "1713614400"}
}'

# Query items for a user
aws dynamodb query \
--table-name UserSessions \
--key-condition-expression "UserId = :uid" \
--expression-attribute-values '{":uid": {"S": "user-123"}}' \
--output table

Read/Write Capacity Modes

ModeHow It WorksBest ForCost Model
On-DemandScales automatically, pay per requestUnpredictable traffic, new apps$1.25 per million write, $0.25 per million read
ProvisionedYou set read/write capacity unitsPredictable traffic, cost optimization~70% cheaper than on-demand at steady state
Provisioned + Auto ScalingAuto-adjusts within min/max boundsVariable but patterned trafficBest of both worlds

Multi-AZ vs Read Replicas

These solve different problems:

FeatureMulti-AZRead Replicas
PurposeHigh availability (failover)Read performance (scale reads)
ReplicationSynchronousAsynchronous
FailoverAutomatic (~60 seconds)Manual (promote to primary)
Read trafficStandby not readableServes read queries
Cost2x instance costPer-replica instance cost
Cross-regionNo (same region)Yes
# Enable Multi-AZ on an existing instance
aws rds modify-db-instance \
--db-instance-identifier my-app-db \
--multi-az \
--apply-immediately

# Create a read replica
aws rds create-db-instance-read-replica \
--db-instance-identifier my-app-db-read \
--source-db-instance-identifier my-app-db \
--db-instance-class db.t3.medium

Automated Backups

RDS and Aurora handle backups differently:

# Modify backup retention (RDS)
aws rds modify-db-instance \
--db-instance-identifier my-app-db \
--backup-retention-period 14 \
--preferred-backup-window "03:00-04:00"

# Create a manual snapshot (on-demand backup)
aws rds create-db-snapshot \
--db-instance-identifier my-app-db \
--db-snapshot-identifier my-app-db-$(date +%Y%m%d)

# Restore from a point in time
aws rds restore-db-instance-to-point-in-time \
--source-db-instance-identifier my-app-db \
--target-db-instance-identifier my-app-db-restored \
--restore-time "2025-04-19T10:00:00Z"

Cost Comparison (db.r6g.large, us-east-1)

DatabaseMonthly CostStorageWhat You Get
RDS PostgreSQL (Single-AZ)~$140$0.115/GBBasic managed database
RDS PostgreSQL (Multi-AZ)~$280$0.23/GBHigh availability failover
Aurora PostgreSQL~$190$0.10/GB (auto-scale)Better performance, auto-scaling storage
Aurora Serverless v2~$0.12/ACU-hour$0.10/GBPay only when active
DynamoDB (On-Demand)Pay per request$0.25/GBZero management

When to Use Each

  • RDS: Standard web apps, existing SQL skills, predictable workloads, tight budgets
  • Aurora: Production workloads needing high availability, read-heavy apps, growing data
  • Aurora Serverless: Dev/test environments, infrequent but spiky workloads
  • DynamoDB: Session stores, user profiles, IoT data, gaming leaderboards, sub-millisecond latency requirements

What's Next?

Databases store your data, but something needs to process it. Next up: AWS Lambda and serverless — how to build your first serverless application with zero infrastructure to manage.


This is Part 7 of our AWS series. Pick your database wisely — migrations are painful and expensive.