Amazon Aurora
Amazon Aurora is AWS’s own relational database engine, built from the ground up to run in the cloud. It speaks the same language as MySQL and PostgreSQL (so your existing apps and drivers work unchanged), but underneath it replaces the storage engine with a custom distributed system that is faster and far more durable than a standard database on a single disk. You run Aurora through Amazon RDS (Relational Database Service, AWS’s managed database service), so you still get automated backups, patching, and monitoring, you just get a much stronger engine doing the heavy lifting.
What makes Aurora different
A normal database writes all its data to one storage volume attached to one server. If that server or disk fails, you wait for a failover or a restore. Aurora separates the database “brain” (the compute instance that runs SQL) from the “disk” (a shared, distributed storage layer that lives across the network).
That storage layer is the key idea. Aurora keeps 6 copies of your data spread across 3 Availability Zones (an Availability Zone, or AZ, is a physically separate data center in an AWS Region). A write is considered successful once 4 of the 6 copies confirm it, so Aurora can lose an entire AZ and two extra copies and still not lose data. Storage is also self-healing: it constantly scans for bad blocks and repairs them from the other copies.
Because the storage is shared, read replicas (extra read-only copies of the database) do not each need their own full copy of the data. They all read from the same distributed volume. This gives Aurora two big advantages:
- Up to 15 read replicas with very low replication lag (often single-digit milliseconds), versus up to 5 on standard RDS.
- Fast failover (typically under 30 seconds) because a replica just gets promoted to be the new writer; it does not need to copy data first.
Aurora vs standard RDS — when to use which
Both run on RDS. The question is whether the Aurora engine is worth it for your workload.
| Factor | Standard RDS (MySQL/PostgreSQL) | Amazon Aurora |
|---|---|---|
| Storage durability | 1 volume, replicated within an AZ | 6 copies across 3 AZs |
| Read replicas | Up to 5, separate volumes | Up to 15, shared volume, low lag |
| Failover time | 60-120 seconds (Multi-AZ) | Usually under 30 seconds |
| Throughput | Good | Up to ~5x MySQL, ~3x PostgreSQL |
| Cost model | Per-GB storage + instance | Per-GB storage + I/O charges + instance |
| Best for | Predictable apps, tight budgets, exotic engine versions | High traffic, many readers, low-downtime needs |
Use Aurora when you need lots of read scaling, very fast failover, or higher write throughput than standard RDS gives you, and you are comfortable on MySQL/PostgreSQL-compatible versions. Stick with standard RDS when your workload is modest and predictable, you want the simplest possible cost model, or you need a specific engine (Oracle, SQL Server, MariaDB) or a database version Aurora does not support yet.
The cost gotcha: I/O is billed separately
This is the trap that surprises people. On standard RDS you mostly pay for the instance and storage. On Aurora’s default configuration (called Aurora Standard) you pay for the instance, for storage per GB-month, and for every read/write I/O operation against the storage layer. A “chatty” application that does millions of small queries can run up a large I/O bill, so Aurora is not always cheaper than RDS, even though it performs better.
AWS offers a second pricing mode, Aurora I/O-Optimized, which removes per-request I/O charges in exchange for a higher instance and storage rate. The rule of thumb: if I/O charges are more than about 25% of your Aurora bill, switch to I/O-Optimized.
Cost warning: Before committing, look at the
VolumeReadIOPsandVolumeWriteIOPsCloudWatch metrics on a test cluster. A workload doing tens of millions of I/Os per day on Aurora Standard can cost more than the same data on plain RDS. Estimate with the AWS Pricing Calculator first.
Creating an Aurora cluster
Aurora is organized as a cluster: one cluster holds the shared storage plus one writer instance and zero or more reader instances.
Console steps
- Open the RDS console and choose Create database.
- Pick Standard create, then under Engine type choose Aurora (MySQL Compatible) or Aurora (PostgreSQL Compatible).
- Choose a template (Production enables Multi-AZ by default).
- Set the cluster identifier, master username, and password.
- Under Instance configuration, pick an instance class (for example
db.r6g.large). - Under Availability & durability, choose Create an Aurora Replica in a different AZ for failover.
- Pick your VPC (Virtual Private Cloud, your isolated network), subnet group, and security group (
sg-0a1b2c3d). - Under Additional configuration, choose the storage type: Aurora Standard or Aurora I/O-Optimized.
- Click Create database.
AWS CLI
Create the cluster, then add a writer instance to it:
aws rds create-db-cluster \
--db-cluster-identifier prod-aurora \
--engine aurora-postgresql \
--engine-version 16.4 \
--master-username admin \
--manage-master-user-password \
--storage-type aurora-iopt1 \
--vpc-security-group-ids sg-0a1b2c3d \
--db-subnet-group-name prod-db-subnets
aws rds create-db-instance \
--db-instance-identifier prod-aurora-writer \
--db-cluster-identifier prod-aurora \
--engine aurora-postgresql \
--db-instance-class db.r6g.large
Output:
{
"DBCluster": {
"DBClusterIdentifier": "prod-aurora",
"Status": "creating",
"Engine": "aurora-postgresql",
"StorageType": "aurora-iopt1",
"Endpoint": "prod-aurora.cluster-c9xexample.us-east-1.rds.amazonaws.com",
"ReaderEndpoint": "prod-aurora.cluster-ro-c9xexample.us-east-1.rds.amazonaws.com"
}
}
Note the two endpoints. The cluster endpoint always points to the current writer. The reader endpoint load-balances connections across all replicas, so point your read traffic there.
Adding read replicas
Each replica is just another instance attached to the same cluster.
aws rds create-db-instance \
--db-instance-identifier prod-aurora-reader-1 \
--db-cluster-identifier prod-aurora \
--engine aurora-postgresql \
--db-instance-class db.r6g.large
In the console: open the cluster, choose Actions > Add reader, pick the instance class and AZ, and create it. Send analytics or dashboard queries to the reader endpoint to keep load off the writer.
Best practices
- Connect writes to the cluster endpoint and reads to the reader endpoint so failovers and scaling are transparent to your app.
- Watch
VolumeReadIOPs/VolumeWriteIOPsin CloudWatch and switch to I/O-Optimized once I/O is more than ~25% of the bill. - Keep at least one reader in a second AZ so failover is fast and automatic.
- Enable Backtrack (Aurora MySQL) or use snapshots to recover from bad deployments without a full restore.
- Use the latest Graviton (
db.r6g/db.r7g) instance classes for better price/performance. - For spiky or unpredictable traffic, evaluate Aurora Serverless so you pay only for the capacity you use.