RDS Multi-AZ is not about scaling; it’s about High Availability, and it achieves this by replicating your primary database instance to a standby instance in a different Availability Zone.

Let’s watch a Multi-AZ deployment in action. Imagine you have a PostgreSQL database running in us-east-1a. When you enable Multi-AZ, RDS automatically provisions a synchronous replica in us-east-1b. All write operations to your primary instance are immediately mirrored to the standby.

{
  "DBInstanceIdentifier": "my-ha-db",
  "DBInstanceClass": "db.r5.large",
  "Engine": "postgres",
  "MultiAZ": true,
  "AvailabilityZone": "us-east-1a",
  "SecondaryAvailabilityZone": "us-east-1b",
  "DBInstanceStatus": "available",
  "Endpoint": "my-ha-db.xxxxxxxxxxxx.us-east-1.rds.amazonaws.com"
}

If the primary instance in us-east-1a fails, RDS performs an automatic failover. Within 60-120 seconds, the standby instance in us-east-1b is promoted to become the new primary, and your application’s endpoint remains the same. Your application reconnects to the new primary, and writes resume. This is HA.

Read Replicas, on the other hand, are designed for scaling read operations. They are asynchronous copies of your primary database. You can create multiple read replicas, each in its own Availability Zone or even region, and direct your read-heavy application traffic to them.

Consider this configuration:

{
  "DBInstanceIdentifier": "my-primary-db",
  "DBInstanceClass": "db.r5.large",
  "Engine": "mysql",
  "MultiAZ": false,
  "AvailabilityZone": "us-east-1a",
  "DBInstanceStatus": "available",
  "Endpoint": "my-primary-db.xxxxxxxxxxxx.us-east-1.rds.amazonaws.com"
},
{
  "DBInstanceIdentifier": "my-read-replica-1",
  "SourceDBInstanceIdentifier": "my-primary-db",
  "DBInstanceClass": "db.r5.large",
  "Engine": "mysql",
  "MultiAZ": false,
  "AvailabilityZone": "us-east-1a",
  "DBInstanceStatus": "available",
  "Endpoint": "my-read-replica-1.xxxxxxxxxxxx.us-east-1.rds.amazonaws.com"
},
{
  "DBInstanceIdentifier": "my-read-replica-2",
  "SourceDBInstanceIdentifier": "my-primary-db",
  "DBInstanceClass": "db.r5.large",
  "Engine": "mysql",
  "MultiAZ": false,
  "AvailabilityZone": "us-east-1b",
  "DBInstanceStatus": "available",
  "Endpoint": "my-read-replica-2.xxxxxxxxxxxx.us-east-1.rds.amazonaws.com"
}

Here, my-primary-db handles all writes, while my-read-replica-1 and my-read-replica-2 serve read queries. This offloads traffic from the primary, improving overall performance and scalability for read-intensive workloads.

The critical difference lies in the replication mechanism. Multi-AZ uses synchronous replication. This means a write is only committed on the primary after it has been successfully written to the standby. This guarantees zero data loss during a failover but can introduce higher write latency. Read Replicas use asynchronous replication. Writes are committed on the primary immediately, and then sent to the replicas. This leads to lower write latency but introduces the possibility of replication lag, meaning read replicas might be slightly behind the primary.

You can also create a Read Replica from a Multi-AZ primary. In this scenario, the Multi-AZ primary’s synchronous replica is not used as the source for the Read Replica. Instead, the Read Replica is created asynchronously from the primary instance. This allows you to have both HA and read scaling from a single primary database.

A common misconception is that a Read Replica can be promoted to a standalone instance. While you can promote a Read Replica, it breaks the replication chain. The promoted replica becomes a new, independent database instance. If the original primary later fails, this promoted replica has no knowledge of it and cannot automatically take over.

The replication lag on a Read Replica is a key metric to monitor. If it grows too large, your read queries might be returning stale data. You can check this using the ReplicaLag metric in CloudWatch.

The instance class of a Read Replica can be different from its source instance. This is a powerful feature for scaling; you can use smaller, cheaper instances for your primary if it’s not under heavy write load, and provision larger, more powerful instances for your read replicas to handle high read volumes.

When you delete a Read Replica, the source database and its other replicas are unaffected. The deletion is a simple removal of that specific replica instance.

The next step in scaling beyond read replicas is often employing database sharding or exploring more advanced caching strategies in front of your database.

Want structured learning?

Take the full Rds course →