Amazon Aurora
AWS’s own MySQL/PostgreSQL-compatible engine — same wire protocol, your client code is unchanged, but the storage layer is completely redesigned: log-structured, distributed across 6 copies in 3 AZs, separated from compute.
The architecture difference
Standard RDS Postgres: one server, attached EBS. Multi-AZ adds a synchronous standby with its own copy.
Aurora: one distributed storage layer that any compute node can attach to. Up to 15 readers, all sharing the same storage. Failover is just promoting one reader to writer (~30s, no data copy).
+----------+ +----------+ +----------+
| writer | | reader 1 | ... | reader N |
+----+-----+ +----+-----+ +----+-----+
| | |
v v v
+-----------------------------------+
| Aurora Storage Layer |
| (6 copies, 3 AZs, log-based) |
+-----------------------------------+
Storage is replicated 6 ways across 3 AZs; writes need 4/6 acks (quorum) to commit. Reads need 3/6. Self-healing — lost copies are rebuilt.
What you actually get
- Failover ~30s vs RDS Multi-AZ’s 60-120s.
- Up to 15 read replicas with seconds of lag (they read the shared storage, no logical replication).
- Aurora Serverless v2 — auto-scales compute (ACUs) up and down with load, including down to ~0.5 ACU at idle. Great for spiky workloads.
- Global Database — cross-region replication with sub-second lag and a managed promote-on-DR.
- Backtrack (MySQL only) — rewind the DB in-place by minutes/hours without restoring from snapshot.
- Faster query performance for most workloads — Aurora’s storage layer skips dirty page writeout to a separate WAL.
When to pick Aurora over RDS
- You need very fast failover.
- You need many read replicas (>5).
- You need cross-region replication with low lag.
- You’re on a workload that benefits from Aurora’s I/O optimizations (write-heavy with lots of
vacuumwork). - You want Serverless v2 for spiky / unpredictable traffic.
When RDS Postgres is enough:
- Small workloads, cost-sensitive.
- You need a specific Postgres extension Aurora doesn’t support.
- You need exact compatibility with on-prem Postgres for an upcoming migration off cloud.
Aurora Serverless v2
The interesting one. Compute is measured in ACUs (Aurora Capacity Units, ~2GB RAM + matching CPU). You set min and max; Aurora scales within that range in seconds.
aws rds modify-db-cluster \
--db-cluster-identifier orders \
--serverless-v2-scaling-configuration MinCapacity=0.5,MaxCapacity=16
- 0.5 ACU minimum → very cheap idle ($0.06/h ≈ $43/month).
- Scales up during traffic spikes without manual intervention.
- Connections preserved during scaling (vs v1, which dropped them).
Gotcha: v2 doesn’t scale to zero like v1 did. The 0.5 minimum runs constantly. v1 still exists for the zero-scale case but with worse cold-start behavior.
Cluster endpoints
Aurora exposes:
- Cluster endpoint (writer) — always points to the current primary, follows failover.
- Reader endpoint — load-balances across read replicas.
- Instance endpoint — direct to a specific node (rarely used).
- Custom endpoints — subset of replicas, e.g., “analytics” replicas with larger instance class.
# typical app config
WRITER = "orders.cluster-xxx.us-east-1.rds.amazonaws.com"
READER = "orders.cluster-ro-xxx.us-east-1.rds.amazonaws.com"
write_engine = create_engine(f"postgresql+psycopg://app@{WRITER}/orders")
read_engine = create_engine(f"postgresql+psycopg://app@{READER}/orders")
Your code routes writes to one engine, reads to the other. Watch read-after-write consistency: a reader may lag by tens of milliseconds. Either route critical reads to the writer, or hold the user on the writer for ~100ms after their write.
Global Database
A primary cluster in one region with up to 5 read-only secondary clusters in other regions, sub-second lag. Promote a secondary to take over in a DR scenario in ~1 minute.
Use cases:
- Multi-region read latency (users in EU read from EU cluster, writes go to US primary).
- DR with low RPO.
Costs add up — every region pays full Aurora pricing.
I/O cost gotcha (Aurora I/O-Optimized)
Standard Aurora charges per I/O operation, which on heavy write workloads can balloon costs. Aurora I/O-Optimized (2023) is a fixed-price tier — no per-I/O charge, ~30% premium on compute and storage. For write-heavy workloads (>25% of bill from I/O), I/O-Optimized is cheaper.
Performance gotchas
- Reader endpoint round-robins on connection, not on query. Long-lived pools stick to one reader; uneven load. Recycle connections periodically or use a layer-7 proxy.
max_connectionsis set by instance class. Switching to a smaller writer drops your ceiling.- Backtrack (MySQL) doesn’t replace backups. It rewinds in place — irreversible after the window expires; can’t recover from “rewound back too far”.
- Serverless v2 scaling has thrash potential if min is set too low. Set min high enough that normal traffic doesn’t trigger scaling constantly.
Aurora Postgres extensions
Most popular ones supported: pgvector, pg_stat_statements, pg_trgm, postgis, uuid-ossp. Some lag the upstream Postgres release. Check the Aurora Postgres release notes before relying on a specific extension version.
Interview angle
- “Aurora vs RDS Postgres?” — Aurora has its own distributed storage layer (6 copies across 3 AZs, log-structured), faster failover (~30s), up to 15 readers sharing storage, Serverless v2 auto-scaling, Global Database for cross-region. RDS Postgres is “managed vanilla Postgres on EBS.” Pick Aurora when you need fast failover, many readers, or auto-scaling.
- “How does Aurora replicate to readers?” — readers don’t apply logical/physical replication. They read the same shared storage layer. Replication lag is milliseconds (storage write latency), not Postgres apply lag.
- “When would you NOT use Aurora?” — small workloads with cost sensitivity (RDS is cheaper at low end), Postgres extensions Aurora doesn’t support, hard requirement for stock Postgres for an upcoming on-prem migration, or workloads where per-I/O pricing dominates the bill.
- “What’s Aurora Serverless v2?” — auto-scaling compute in ACUs (CPU+RAM units), scales in seconds without dropping connections. Min 0.5 ACU (doesn’t go to zero like v1). Best for spiky / unpredictable workloads.
- “How would you do read-write splitting?” — route to the cluster (writer) endpoint for writes, reader endpoint for reads. Watch for read-after-write consistency — a reader may lag by milliseconds. For just-written data, either route the read to the writer or wait briefly.
- “What’s the I/O cost gotcha?” — standard Aurora bills per I/O operation; write-heavy workloads can rack up massive I/O bills. Aurora I/O-Optimized has flat I/O pricing (~30% premium on compute). Check the bill — if I/O is >25%, switch.