What is Amazon Aurora and How is it Different from Standard RDS MySQL
When you open the RDS console and see both 'Aurora MySQL' and 'MySQL' as engine options, the natural question is: what exactly are you paying more for? Aurora is not just a managed MySQL wrapper — it's a fundamentally different storage architecture that happens to speak the MySQL protocol. Understanding that distinction is what determines whether Aurora is the right call for your workload or an expensive over-engineering choice.
TL;DR: Aurora MySQL vs. Standard RDS MySQL
| Dimension | Aurora MySQL | Standard RDS MySQL |
|---|---|---|
| Storage architecture | Distributed, shared cluster volume | EBS volume attached per instance |
| MySQL compatibility | Compatible with MySQL 5.7 / 8.0 (wire protocol) | Runs actual MySQL community engine |
| Read replicas | Up to 15, share same storage, near-zero lag | Up to 5, each replicates data independently |
| Failover | Typically under 30 seconds (documented) | 60-120 seconds typical (new EBS attach) |
| Storage scaling | Auto-grows in 10 GiB increments, up to 128 TiB | Manual or autoscaling, EBS-bound |
| Cost | Higher per instance + I/O charges (or Aurora I/O-Optimized) | Lower instance cost, EBS pricing model |
| Serverless option | Aurora Serverless v2 available | Not available |
How Aurora MySQL Actually Works
The core difference is not the compute layer — it's the storage layer. Standard RDS MySQL runs the MySQL engine on an EC2 instance backed by an EBS volume. Replication to read replicas means physically shipping binlog events, applying them on each replica's own EBS volume. Failover means detaching and reattaching EBS, which takes time.
Aurora separates compute from storage entirely. All instances in an Aurora cluster — the writer and up to 15 readers — share a single distributed storage volume that spans three Availability Zones, with six copies of your data across those AZs (two per AZ). The MySQL-compatible compute layer sits on top and talks to this shared volume via a proprietary storage protocol.
(Writer DNS)"] App --> RE["Reader Endpoint
(Load Balanced)"] CE --> Writer["Writer Instance"] RE --> R1["Reader Instance 1"] RE --> R2["Reader Instance 2"] Writer --> SV["Shared Cluster Volume
6 nodes across 3 AZs"] R1 --> SV R2 --> SV SV --> AZ1["AZ-1: 2 nodes"] SV --> AZ2["AZ-2: 2 nodes"] SV --> AZ3["AZ-3: 2 nodes"] style SV fill:#f0f4ff,stroke:#4a6cf7 style Writer fill:#fff3e0,stroke:#ff9800 style R1 fill:#e8f5e9,stroke:#4caf50 style R2 fill:#e8f5e9,stroke:#4caf50
- Writer instance handles all DDL and DML writes. It sends log records (not full pages) to the distributed storage layer.
- Distributed storage spans 3 AZs with 6 storage nodes. Writes are acknowledged after 4 of 6 nodes confirm — this is Aurora's quorum model.
- Reader instances read directly from the same shared storage volume. There is no binlog shipping, so replica lag is measured in single-digit milliseconds under normal conditions.
- Cluster endpoint routes writes to the writer; reader endpoint load-balances across readers. Your application connects to endpoints, not instance hostnames.
Think of standard RDS MySQL like each employee having their own filing cabinet that gets a photocopy of every document. Aurora is more like everyone sharing a single filing room — the room itself is redundant and distributed, but there's only one authoritative copy of each document.
MySQL Compatibility: What Works and What Doesn't
Aurora MySQL is wire-protocol compatible with MySQL 5.7 and 8.0. Most applications migrate without code changes. The MySQL client, JDBC drivers, and ORMs connect identically. Standard SQL, stored procedures, triggers, and views work as expected.
Where compatibility has limits:
- Storage engine: Aurora uses its own storage engine internally. MyISAM tables are not supported. InnoDB is the only supported engine, which is already the MySQL default for most workloads.
- Some MySQL system variables behave differently or are read-only in Aurora. Always test parameter group settings against the Aurora MySQL documentation rather than assuming MySQL 8.0 parity.
- Replication topology: Aurora has its own replication model. Configuring Aurora as a replica of an external MySQL instance (or vice versa) is possible but requires specific setup — it doesn't behave like standard MySQL binlog replication between two community instances.
- Aurora-specific features like Aurora Global Database, Backtrack, and Aurora Serverless v2 have no equivalent in standard RDS MySQL.
Why Aurora MySQL Costs More — and When That Cost is Justified
Aurora charges for compute (instance hours), storage (per GiB-month), and I/O (per million requests in the standard pricing tier). Standard RDS MySQL charges for compute and EBS storage/IOPS, with no per-I/O charge at the database layer.
For read-heavy workloads, the economics often flip. Adding a read replica in standard RDS means provisioning a full instance with its own EBS volume and paying for the storage twice. In Aurora, a reader instance shares the existing storage — you pay only for the additional compute. At scale with multiple read replicas, Aurora's total cost can be lower despite the higher base price.
Aurora I/O-Optimized (a pricing tier introduced in 2023) eliminates per-I/O charges in exchange for a higher instance and storage price. For I/O-intensive workloads, this tier can reduce costs significantly — AWS states it can save up to 40% for I/O-heavy workloads, but verify against your actual I/O patterns before switching.
Aurora makes sense when:
- You need more than 5 read replicas
- Failover time under 30 seconds matters for your SLA
- You want cross-region replication with Aurora Global Database
- You need Aurora Serverless v2 for variable or unpredictable workloads
- Storage growth is unpredictable and you want automatic scaling without pre-provisioning
Standard RDS MySQL makes sense when:
- Your workload is small or medium with predictable I/O
- You need a specific MySQL minor version that Aurora hasn't adopted yet
- Cost sensitivity is high and the Aurora feature set isn't required
- You're running dev/test environments where HA characteristics don't matter
Failover Behavior: The Operational Difference That Matters Most
This is where the architectural difference becomes a real operational concern. In standard RDS MySQL, a failover requires promoting a replica, which means the new primary must have an EBS volume with the replicated data. The DNS endpoint is updated to point to the new instance. This process typically takes 60 seconds or more depending on instance class and I/O activity at the time of failure.
In Aurora, failover promotes an existing reader to writer. Because all instances share the same storage volume, there's no data to copy or replay. Aurora updates the cluster endpoint DNS record to point to the promoted reader. AWS documents this as typically completing in under 30 seconds, and with Aurora Serverless v2 or application-level connection retry logic, many workloads experience this as a brief connection interruption rather than a full outage.
storage already shared R1->>SV: Begins accepting writes CE-->>App: DNS updated to R1 App->>CE: Reconnects (under 30s typical) CE->>R1: Routes to new writer
A Real Misdiagnosis: Replica Lag That Wasn't Replication Lag
A team migrated from RDS MySQL to Aurora MySQL expecting replica lag to drop to near-zero. After migration, their monitoring still showed replica lag spiking to several seconds during batch jobs. The assumption was that Aurora's shared storage would eliminate this entirely.
The actual cause: they were measuring ReplicaLag in CloudWatch, which for Aurora reflects the lag in applying log records to the reader's buffer cache — not binlog replication lag. The batch jobs were generating large volumes of writes that the reader instances needed time to apply to their in-memory state, even though the underlying storage was already consistent. The fix was not a replication tuning issue — it was right-sizing the reader instances to handle the cache invalidation workload from the batch writes. The storage layer was fine; the compute layer was undersized for the read workload pattern.
Insight: Aurora's replica lag metric measures something fundamentally different from MySQL binlog replication lag. Don't assume the same metric means the same thing after migration.
Key CLI Operations for Aurora MySQL
Creating an Aurora MySQL cluster requires creating the cluster first, then adding instances to it — unlike standard RDS where a single create-db-instance call is sufficient.
🔽 Create Aurora MySQL Cluster (Click to expand)
# Step 1: Create the Aurora cluster (storage layer)
aws rds create-db-cluster \
--db-cluster-identifier my-aurora-cluster \
--engine aurora-mysql \
--engine-version 8.0.mysql_aurora.3.04.0 \
--master-username admin \
--master-user-password 'YourSecurePassword' \
--db-subnet-group-name my-subnet-group \
--vpc-security-group-ids sg-0123456789abcdef0 \
--backup-retention-period 7 \
--region us-east-1
# Step 2: Add the writer instance to the cluster
aws rds create-db-instance \
--db-instance-identifier my-aurora-writer \
--db-cluster-identifier my-aurora-cluster \
--db-instance-class db.r6g.large \
--engine aurora-mysql \
--region us-east-1
# Step 3: Add a reader instance
aws rds create-db-instance \
--db-instance-identifier my-aurora-reader-1 \
--db-cluster-identifier my-aurora-cluster \
--db-instance-class db.r6g.large \
--engine aurora-mysql \
--region us-east-1
🔽 Describe Cluster Endpoints (Click to expand)
# Retrieve cluster endpoints (writer and reader)
aws rds describe-db-clusters \
--db-cluster-identifier my-aurora-cluster \
--query 'DBClusters[0].{WriterEndpoint:Endpoint,ReaderEndpoint:ReaderEndpoint,Status:Status}' \
--output table \
--region us-east-1
🔽 Check Replica Lag via CloudWatch (Click to expand)
# Check AuroraReplicaLag for a specific reader instance
aws cloudwatch get-metric-statistics \
--namespace AWS/RDS \
--metric-name AuroraReplicaLag \
--dimensions Name=DBInstanceIdentifier,Value=my-aurora-reader-1 \
--start-time 2024-01-01T00:00:00Z \
--end-time 2024-01-01T01:00:00Z \
--period 60 \
--statistics Average \
--region us-east-1
IAM Permissions for Aurora Cluster Management
Managing Aurora clusters requires permissions at both the cluster and instance level. Note that several Describe actions require Resource: "*" as they do not support resource-level restrictions.
🔽 Minimum IAM Policy for Aurora Operations (Click to expand)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AuroraClusterManagement",
"Effect": "Allow",
"Action": [
"rds:CreateDBCluster",
"rds:DeleteDBCluster",
"rds:ModifyDBCluster",
"rds:DescribeDBClusters",
"rds:CreateDBInstance",
"rds:DeleteDBInstance",
"rds:ModifyDBInstance",
"rds:DescribeDBInstances",
"rds:DescribeDBClusterEndpoints",
"rds:FailoverDBCluster"
],
"Resource": "*"
},
{
"Sid": "AuroraClusterARNScoped",
"Effect": "Allow",
"Action": [
"rds:AddTagsToResource",
"rds:RemoveTagsFromResource"
],
"Resource": [
"arn:aws:rds:us-east-1:123456789012:cluster:my-aurora-cluster",
"arn:aws:rds:us-east-1:123456789012:db:my-aurora-writer",
"arn:aws:rds:us-east-1:123456789012:db:my-aurora-reader-1"
]
}
]
}
Wrap-Up: Choosing Between Aurora MySQL and Standard RDS MySQL
Aurora MySQL is not a drop-in upgrade for every workload — it's a different storage architecture that happens to be MySQL-compatible. The higher cost reflects real engineering: distributed storage, faster failover, shared-volume read replicas, and automatic storage growth. For production workloads where availability, read scalability, or storage unpredictability are concerns, Aurora MySQL frequently justifies its price. For smaller or cost-sensitive workloads without those requirements, standard RDS MySQL remains a solid, simpler choice.
Before committing, run a cost estimate using the Aurora pricing page against your expected instance hours, storage GiB, and I/O request volume. The I/O-Optimized tier is worth evaluating separately if your workload is write-heavy.
For further reading, see the Amazon Aurora MySQL documentation and the Aurora replication overview.
Glossary
| Term | Definition |
|---|---|
| Aurora Cluster Volume | The distributed, shared storage layer underlying an Aurora cluster, spanning 3 AZs with 6 storage nodes. |
| Cluster Endpoint | A DNS endpoint that always routes to the current writer instance in an Aurora cluster. |
| Reader Endpoint | A load-balanced DNS endpoint that distributes read connections across all available Aurora reader instances. |
| AuroraReplicaLag | CloudWatch metric measuring the lag for a reader instance to apply log records from the writer — distinct from MySQL binlog replication lag. |
| Aurora I/O-Optimized | An Aurora pricing configuration that eliminates per-I/O charges in exchange for higher instance and storage rates, beneficial for I/O-intensive workloads. |
Related Posts
- 📄 RDS Multi-AZ Benefits: High Availability, Failover, and What It Won't Do for Performance
- 📄 Scaling Reads with RDS Read Replicas: Architecture, Setup, and the Multi-AZ Difference
- 📄 Connecting to AWS RDS MySQL from Your Local Machine: Public Access, Security Groups, and Safer Alternatives
- 📄 RDS Running Out of Storage: How to Use Storage Autoscaling to Avoid Downtime
- 📄 Restoring RDS from a Snapshot: New Instance, New Endpoint — Here's What Changes
Comments
Post a Comment