Skip to content
Codeloom
AWS

AWS RDS vs Aurora: Managed Database Comparison

Compare AWS RDS and Aurora for MySQL and PostgreSQL workloads. Learn architecture differences, performance, pricing, and when to choose each service.

·8 min read · By Codeloom
Intermediate 17 min read

What you'll learn

  • Understand the architectural differences between RDS and Aurora
  • Compare performance, availability, and pricing for each option
  • Configure Aurora with read replicas and global databases
  • Choose the right managed database for your workload

Prerequisites

  • Basic understanding of relational databases
  • AWS account with VPC configured

AWS offers two managed relational database services: Amazon RDS and Amazon Aurora. Both handle backups, patching, and replication, but they are built on fundamentally different architectures. Choosing between them affects your application’s performance, availability, and monthly bill.

This guide breaks down the differences with real numbers and configurations so you can make an informed decision.

Architecture: The Core Difference

Amazon RDS runs traditional database engines (MySQL, PostgreSQL, MariaDB, Oracle, SQL Server) on EC2 instances with EBS volumes. The architecture is similar to what you would set up yourself, but AWS manages the operational overhead. Each RDS instance has its own storage, and replication works by streaming write-ahead logs to standby instances.

Amazon Aurora is AWS’s re-engineered database service compatible with MySQL and PostgreSQL. The key innovation is the storage layer: Aurora separates compute from storage. All Aurora instances in a cluster share a single distributed storage volume that automatically replicates data six ways across three Availability Zones.

# RDS Architecture (simplified)
Primary Instance:
  - Compute: db.r6g.xlarge
  - Storage: gp3 EBS volume (instance-attached)
  - Replication: Streaming WAL to standby

Standby Instance:
  - Compute: db.r6g.xlarge
  - Storage: Separate gp3 EBS volume (full copy)

# Aurora Architecture (simplified)
Aurora Cluster:
  Writer Instance:
    - Compute: db.r6g.xlarge
    - Storage: Shared Aurora storage (no EBS)
  Reader Instance(s):
    - Compute: db.r6g.xlarge
    - Storage: Same shared storage (no replication lag for storage)

  Storage Layer:
    - 6 copies across 3 AZs
    - Auto-scales from 10 GB to 128 TB
    - Continuous backup to S3

This architectural difference drives most of the performance and availability differences.

Performance Comparison

Aurora claims up to 5x throughput over MySQL RDS and 3x over PostgreSQL RDS. Real-world results vary, but Aurora consistently outperforms RDS in several areas:

Write performance. Aurora only writes redo log records to the storage layer, not full data pages. This reduces write amplification by roughly 6x compared to RDS, which must write full pages to EBS.

Read replica lag. RDS replicas use asynchronous streaming replication and typically lag 10-100ms behind the primary. Aurora replicas share the same storage, so lag is usually under 10ms and often under 1ms.

Failover time. RDS Multi-AZ failover takes 60-120 seconds because the standby must be promoted and DNS must propagate. Aurora failover typically completes in under 30 seconds because replicas already have access to the shared storage.

Connection handling. Aurora supports up to 5,000 connections per instance compared to the lower limits on standard RDS instances of the same size.

Here is a practical benchmark comparison:

# pgbench on RDS PostgreSQL (db.r6g.xlarge)
pgbench -c 100 -j 4 -T 300 -U admin -h rds-endpoint mydb
# Typical result: ~2,500 TPS

# pgbench on Aurora PostgreSQL (db.r6g.xlarge)
pgbench -c 100 -j 4 -T 300 -U admin -h aurora-endpoint mydb
# Typical result: ~5,800 TPS

The gap widens with write-heavy workloads because of Aurora’s more efficient write path.

High Availability

Both services offer high availability, but the mechanisms differ:

RDS Multi-AZ deploys a synchronous standby replica in another AZ. The standby cannot serve read traffic (unless you use readable standbys with Multi-AZ cluster deployment). Failover requires promoting the standby, updating DNS, and potentially recovering from the last checkpoint.

Aurora provides high availability by default through its storage layer. Even a single Aurora instance stores data across three AZs. Adding Aurora replicas gives you read scaling and faster failover targets:

Resources:
  AuroraCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      Engine: aurora-postgresql
      EngineVersion: "15.4"
      MasterUsername: admin
      MasterUserPassword: !Ref DBPassword
      DatabaseName: myapp
      DBSubnetGroupName: !Ref DBSubnetGroup
      VpcSecurityGroupIds:
        - !Ref DatabaseSecurityGroup
      BackupRetentionPeriod: 30
      DeletionProtection: true
      StorageEncrypted: true

  AuroraWriterInstance:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref AuroraCluster
      DBInstanceClass: db.r6g.xlarge
      Engine: aurora-postgresql
      PubliclyAccessible: false

  AuroraReaderInstance1:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref AuroraCluster
      DBInstanceClass: db.r6g.large
      Engine: aurora-postgresql
      PubliclyAccessible: false

  AuroraReaderInstance2:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref AuroraCluster
      DBInstanceClass: db.r6g.large
      Engine: aurora-postgresql
      PubliclyAccessible: false

Aurora also offers Global Databases for cross-region disaster recovery with under 1-second replication lag:

# Create a global cluster
aws rds create-global-cluster \
  --global-cluster-identifier my-global-db \
  --source-db-cluster-identifier arn:aws:rds:us-east-1:123456789012:cluster:my-aurora-cluster \
  --engine aurora-postgresql

# Add a secondary region
aws rds create-db-cluster \
  --db-cluster-identifier my-aurora-secondary \
  --engine aurora-postgresql \
  --global-cluster-identifier my-global-db \
  --region eu-west-1

Storage and Scaling

RDS storage uses EBS volumes. You choose the type (gp3, io1, io2) and allocate a specific size. Storage auto-scaling is available but has limits. Maximum storage is 64 TB. IOPS depend on the EBS volume type and size.

Aurora storage auto-scales automatically from 10 GB to 128 TB with no performance impact. You do not provision storage or choose volume types. Aurora provides consistent performance regardless of data size, with a baseline of thousands of IOPS that scales with the cluster.

# RDS: You must provision and manage storage
aws rds modify-db-instance \
  --db-instance-identifier my-rds-instance \
  --allocated-storage 500 \
  --iops 10000 \
  --storage-type io1

# Aurora: Storage scales automatically. No action needed.
# Monitor storage usage:
aws cloudwatch get-metric-statistics \
  --namespace AWS/RDS \
  --metric-name VolumeBytesUsed \
  --dimensions Name=DBClusterIdentifier,Value=my-aurora-cluster \
  --start-time 2026-06-01T00:00:00Z \
  --end-time 2026-07-01T00:00:00Z \
  --period 86400 \
  --statistics Average

Aurora also offers Aurora Serverless v2, which auto-scales compute capacity in increments of 0.5 ACU (Aurora Capacity Units) based on load:

  AuroraServerlessInstance:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref AuroraCluster
      DBInstanceClass: db.serverless
      Engine: aurora-postgresql

  # Set scaling limits on the cluster
  AuroraCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      Engine: aurora-postgresql
      ServerlessV2ScalingConfiguration:
        MinCapacity: 0.5
        MaxCapacity: 32

Serverless v2 is excellent for variable workloads. It can scale from 0.5 ACU during quiet periods to 32+ ACU during traffic spikes, in seconds.

Pricing Comparison

Pricing differs significantly between the two services. Here is a comparison for a common production setup in us-east-1:

# RDS PostgreSQL - Multi-AZ
Instance: db.r6g.xlarge (2 instances for Multi-AZ)
  On-demand: $0.48/hr x 2 = $0.96/hr = $700/month
Storage: 500 GB gp3
  Cost: $0.08/GB = $40/month
Backup: 500 GB beyond free retention
  Cost: $0.095/GB = $47.50/month
Total: ~$788/month

# Aurora PostgreSQL - Writer + 1 Reader
Writer: db.r6g.xlarge
  On-demand: $0.58/hr = $423/month
Reader: db.r6g.large
  On-demand: $0.29/hr = $212/month
Storage: 500 GB
  Cost: $0.10/GB = $50/month
I/O: ~10 million I/Os
  Cost: $0.20 per million = $2/month
Backup: Included (continuous to S3)
Total: ~$687/month

Aurora instances cost about 20% more per hour than equivalent RDS instances, but the total cost can be lower because:

  • Aurora storage is more efficient (no EBS provisioning waste)
  • Continuous backups to S3 are included
  • Read replicas share storage (no duplicate EBS volumes)
  • You often need fewer, smaller replicas because of better performance

For very small databases (under 100 GB, low traffic), RDS is usually cheaper. For larger workloads with read replicas, Aurora often wins.

Aurora I/O-Optimized vs Standard

Aurora offers two storage pricing models:

Standard: Pay per I/O request ($0.20 per million) plus lower storage cost ($0.10/GB). Best for low to moderate I/O workloads.

I/O-Optimized: No per-I/O charges, but 30% higher storage cost ($0.225/GB). Best for I/O-intensive workloads where I/O costs exceed 25% of total Aurora spend.

# Switch to I/O-Optimized
aws rds modify-db-cluster \
  --db-cluster-identifier my-aurora-cluster \
  --storage-type aurora-iopt1 \
  --apply-immediately

Check your current I/O costs in Cost Explorer. If they are a significant portion of your Aurora bill, I/O-Optimized can save 25-40%.

When to Choose RDS

Pick RDS when:

  • You need Oracle or SQL Server. Aurora only supports MySQL and PostgreSQL.
  • Your database is small and simple. A single-instance RDS setup with minimal storage is the cheapest option for small workloads.
  • You need specific engine versions. RDS supports a wider range of MySQL and PostgreSQL versions, including older ones.
  • You want predictable pricing. RDS pricing is straightforward with no per-I/O charges (on gp3 or io1/io2).

When to Choose Aurora

Pick Aurora when:

  • You need high availability with fast failover. Aurora’s sub-30-second failover is significantly faster than RDS.
  • You have multiple read replicas. Aurora replicas share storage, making them cheaper and faster to add.
  • Your workload is write-heavy. Aurora’s log-based write path delivers significantly better write throughput.
  • You need auto-scaling storage. Aurora eliminates the need to provision and manage EBS volumes.
  • You need cross-region replication. Aurora Global Databases provide sub-second replication lag.
  • Your workload is variable. Aurora Serverless v2 can scale compute to match demand.

Migration Path: RDS to Aurora

Migrating from RDS to Aurora is straightforward for MySQL and PostgreSQL:

# Method 1: Create Aurora Read Replica from RDS (minimal downtime)
aws rds create-db-cluster \
  --db-cluster-identifier aurora-migration \
  --engine aurora-postgresql \
  --replication-source-identifier arn:aws:rds:us-east-1:123456789012:db:my-rds-instance

# Wait for replica to catch up, then promote
aws rds promote-read-replica-db-cluster \
  --db-cluster-identifier aurora-migration

# Method 2: Snapshot and restore (involves downtime)
aws rds restore-db-cluster-from-snapshot \
  --db-cluster-identifier aurora-from-snapshot \
  --snapshot-identifier my-rds-snapshot \
  --engine aurora-postgresql

Method 1 minimizes downtime to seconds during the promotion step. Method 2 is simpler but requires downtime equal to the restore duration.

Wrapping Up

RDS and Aurora solve similar problems but with different architectures, performance characteristics, and pricing models. RDS is the simpler, more predictable option that works well for small to medium workloads and when you need Oracle or SQL Server. Aurora is the better choice for demanding workloads that need high write throughput, fast failover, auto-scaling storage, and efficient read replicas. For most production PostgreSQL and MySQL deployments, Aurora’s advantages in performance and availability justify the slightly higher per-instance cost.