Amazon Aurora

5 min read index source

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 vacuum work).
  • 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_connections is 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.