Aurora Replicas vs RDS Read Replicas: Replication Lag and Limits#
When designing read-heavy database architectures on AWS, the choice between Aurora and standard RDS is rarely about the database engine alone. The replication mechanism fundamentally shapes how your application will behave under load, how quickly read replicas can become standalone databases, and whether you can scale reads cost-effectively. Understanding these differences isn’t just theoretical knowledge—it directly impacts your ability to design resilient, performant systems that meet both functional and business requirements.
Let’s explore why Aurora replicas and RDS read replicas behave so differently, what those differences mean for your architecture, and how to choose the right approach for your specific workload.
The Fundamental Architecture Difference#
The core distinction between Aurora and standard RDS read replicas stems from how each manages storage and replication. This difference cascades through nearly every other characteristic we’ll discuss.
Aurora uses a distributed, shared-storage architecture. All instances in an Aurora cluster—whether primary or replica—connect to the same underlying storage layer. Think of it like multiple servers reading from and writing to the same network-attached storage system. The primary instance handles writes, but read replicas can fetch data directly from this shared storage without waiting for the primary to push changes to them. The replication happens at the storage layer itself, not at the database engine level. This design means Aurora instances are more like multiple compute engines sitting on top of a single highly available storage substrate.
Standard RDS, by contrast, uses the traditional master-replica replication model. The primary database instance executes transactions and generates a stream of changes—typically through binary logs for MySQL, transaction logs for PostgreSQL, or equivalent mechanisms. These changes are then asynchronously transmitted to read replica instances, which apply them to their own local storage. Each replica has its own complete copy of the database on its own storage volume. The replica is constantly playing catch-up, processing the stream of changes from the primary.
This architectural divergence explains virtually everything else that differs between them.
Replication Lag: Single-Digit Milliseconds vs Multiple Seconds#
Replication lag is the delay between when a write commits on the primary and when that change is visible on a read replica. This metric matters enormously because it determines whether a read replica can satisfy read-after-write consistency requirements, and how stale your data can become under load.
Aurora replicas typically exhibit replication lag measured in single-digit milliseconds—often 1 to 5 milliseconds under normal conditions. Because Aurora replicas share the same storage volume, they don’t need to wait for the primary instance to serialize changes and transmit them over the network. The storage layer itself handles the distribution of changes, making the lag nearly imperceptible. You can issue a write to the primary, immediately redirect a subsequent read to a replica, and nearly always get consistent results.
Standard RDS read replicas experience replication lag measured in seconds or more. Under moderate to heavy write load, this lag can easily reach 10, 30, or even 100+ seconds. Why? Because the primary instance must serialize all changes into a binary log, transmit that log to each replica over the network, and the replica must then deserialize and apply those changes sequentially. Network latency, log I/O capacity, and the replica’s ability to apply changes all factor in. If your primary is experiencing a spike in write throughput, the replicas will lag further behind.
This difference has immediate architectural consequences. If your application requires read-after-write consistency—where a user performs an action, then immediately views the results—an RDS read replica is almost certainly the wrong choice. You’d need to direct that read back to the primary. Aurora replicas, however, can often absorb these reads reliably. Applications that can tolerate eventual consistency find RDS replicas much more feasible, but you need to explicitly handle the possibility of stale reads in your application logic.
Under real-world conditions, the lag difference becomes even more pronounced. Imagine a batch job writing thousands of rows per second to your primary. An Aurora replica will be nearly caught up continuously. An RDS read replica might lag several minutes behind, making it unsuitable for any reads that care about recent data.
Maximum Replica Count: 15 vs 5#
Aurora allows up to 15 replicas per cluster, while standard RDS supports only 5 read replicas. This difference reflects both the architectural efficiency of Aurora’s shared-storage model and the practical limits of replication streams in traditional databases.
With standard RDS, every read replica needs its own dedicated replication stream from the primary. These streams consume network bandwidth, CPU resources on the primary (to serialize and transmit logs), and storage I/O. Adding a sixth read replica isn’t just a matter of spinning up another instance—it meaningfully increases load on the primary, which can degrade write performance. AWS enforces the limit of 5 at the account level to protect your primary instance and overall system health.
Aurora’s 15-replica limit exists in a fundamentally different context. Because replicas don’t require individual replication streams, adding more read replicas doesn’t proportionally increase the burden on the primary. The shared storage layer distributes reads efficiently across all available instances. You can scale reads horizontally much further without destabilizing your primary instance. This makes Aurora substantially more suitable for read-heavy workloads with unpredictable or growing read demand.
Note that these limits apply to direct replicas in the same region. Aurora supports additional cross-region replicas through Aurora Global Database (up to 5 secondary regions), which is a separate feature providing read-only access and disaster recovery capabilities. Standard RDS also supports cross-region read replicas, but the same 5-replica limit applies across all replicas, whether in-region or cross-region.
Promotion Semantics and Failover Behavior#
When you promote a replica to become a standalone database, the mechanics differ between Aurora and RDS, with significant implications for downtime and data consistency.
Promoting an Aurora replica is nearly instantaneous. Because the replica already shares storage with the original cluster, promotion primarily involves changing which instance handles writes to that shared storage layer. The replica doesn’t need to “catch up” or wait for the primary to flush its logs. There’s no copying or synchronization required. You can promote an Aurora replica in a matter of seconds, and the promoted instance begins accepting writes immediately with zero data loss (assuming the replica wasn’t lagging at all, which is nearly guaranteed given the single-digit millisecond lag). For planned failovers, Aurora typically achieves failover times of 30 seconds or less.
Promoting an RDS read replica is also relatively fast but requires more work. The replica must stop applying changes from the primary, be promoted to a standalone instance, and then become available for writes. This process typically takes a few minutes. More importantly, if the replica was lagging—which it almost certainly was—you’re promoting a database that’s behind the primary. Any writes that occurred after the replica’s last applied change are lost. This is why RDS read replica promotion is generally used only when the primary has become unavailable (an emergency failover scenario) rather than for planned maintenance or load shifting.
Automatic failover in Aurora clusters is orchestrated by Aurora itself. If the primary instance fails, Aurora automatically promotes one of the replicas to become the new primary. This happens without manual intervention and is designed to be transparent to applications. Because of Aurora’s shared storage and low replication lag, the promoted replica is nearly current with the failed primary. This automatic failover capability is a significant advantage in achieving high availability without human intervention.
Standard RDS doesn’t provide automatic failover in the traditional sense. If your primary fails, you must manually promote a read replica (or trigger a snapshot restore from the latest backup). Some automation frameworks can help detect primary failure and trigger promotion, but it’s not built into the RDS service itself. If you need true automatic failover with RDS, you’d typically use RDS Multi-AZ deployment, which maintains a synchronous standby replica in a different availability zone. Multi-AZ failover is automatic but doesn’t give you a readable replica—the standby is hidden from applications.
This is a critical distinction: Aurora provides automatic failover with readable replicas, while RDS requires you to choose between automatic failover (Multi-AZ, but not readable) and readable replicas (manual promotion in a failure scenario).
Read Distribution and Load Balancing#
How applications distribute reads across replicas also differs meaningfully.
Aurora provides an elegant solution through the reader endpoint. Rather than managing individual replica endpoints in your application code, you configure your read queries to use a single DNS name that automatically distributes connections across available replicas using a round-robin algorithm. This means you can add or remove replicas, and your application connection string doesn’t need to change. If a replica becomes unhealthy, the endpoint automatically stops routing connections to it. The reader endpoint makes scaling reads in Aurora almost seamless from the application perspective.
Standard RDS gives you explicit endpoint addresses for each read replica, plus the primary endpoint. Your application must be aware of all replica endpoints and implement its own load balancing logic—or use a tool like ProxySQL or pgBouncer to distribute connections. If you want to add a new read replica, you might need to update your application configuration to include its endpoint. This is more flexible in some scenarios (you could route specific queries to specific replicas based on business logic) but also more complex to manage and maintain.
Consistency Guarantees and Application Design#
The replication lag difference directly influences how you design applications.
Aurora’s minimal replication lag means you can often use replicas for reads that require recent consistency without special handling. A user’s session might consistently use replicas for reads without risking stale data most of the time. However, explicit read-after-write guarantees still require careful design—you might use session tokens or other application-level mechanisms to ensure reads follow writes.
Standard RDS, with its multi-second lag, requires much more explicit handling. If your application needs read-after-write consistency, you must route those reads back to the primary. Many applications implement a pattern where write operations return the data just written, bypassing the replica reads entirely. Or you use replica read stickiness, where a session always uses the primary until a certain time has passed. These patterns work, but they add complexity and reduce the benefit of having multiple read endpoints.
Cost and Resource Considerations#
From a cost perspective, both approaches charge for compute instances (replicas cost the same as primary instances) and storage. However, the operational model differs.
Aurora charges for both compute (instances) and storage (actual data volume), with storage automatically scaling. If you have 15 replicas in Aurora, you’re paying for 16 instances (primary + 15) but only one copy of storage. The storage is shared across all instances.
Standard RDS charges for instances and storage, with each read replica getting its own storage volume (a complete copy of the database). If you have 5 read replicas, you’re paying for 6 storage volumes containing identical data. This becomes expensive with large databases. However, if you have many small replicas needed for geographic distribution or disaster recovery, RDS’s explicit replica management might be more cost-effective than Aurora’s architecture.
For read-heavy workloads where you want many replicas in the same region, Aurora is almost always more cost-effective because you’re not duplicating storage.
Choosing Between Aurora and RDS Read Replicas#
Here’s a practical framework for deciding which approach fits your needs.
Choose Aurora if your workload is read-heavy with many replicas needed in the same region or cluster, if you need very low replication lag, if automatic failover without manual intervention is important, or if operational simplicity is a priority. Aurora’s reader endpoint and shared storage make managing many replicas significantly easier than with standard RDS.
Choose standard RDS if you need strong consistency guarantees and are willing to route all reads requiring recent data to the primary (so replicas are primarily for disaster recovery or off-peak analytics), if you want explicit control over exactly which queries go to which instances, if you need cross-region read replicas with different characteristics (perhaps different instance types), or if you have significant existing tooling and processes built around RDS read replicas.
Consider RDS Multi-AZ if automatic failover is critical but you don’t need readable replicas. Multi-AZ provides synchronous replication and transparent failover but doesn’t give you a readable standby.
For truly massive read workloads, Aurora’s 15-replica limit might eventually require partitioning your data or using additional caching layers (like ElastiCache) regardless of which database you choose.
Performance Under Load#
Let’s consider a concrete scenario. Imagine you’re building a real-time analytics dashboard that needs to serve hundreds of concurrent read requests while your application continues writing transactional data.
With Aurora, you can provision 10-15 read replicas, distribute connections across them using the reader endpoint, and experience minimal replication lag. Dashboard queries see data that’s typically less than 10 milliseconds behind the current state. Your application’s write performance isn’t significantly affected because replicas don’t consume replication stream resources. Scaling is straightforward: need more read capacity? Add another replica and the reader endpoint automatically balances traffic.
With standard RDS, you’re limited to 5 read replicas, and they’re likely lagging by several hundred milliseconds to several seconds during peak write traffic. The dashboard queries must handle potential staleness, perhaps by falling back to the primary for the most time-sensitive metrics. Adding that fifth replica noticeably increases load on your primary instance. If traffic grows further, you’ve hit the replica limit and must either use caching, change your data model, or switch databases.
The Aurora scenario scales more gracefully and provides better user experience with less application complexity.
Monitoring and Observability#
Both Aurora and RDS provide CloudWatch metrics to monitor replication lag, but Aurora’s metrics are more granular and useful because lag is genuinely minimal. With Aurora, if you see replication lag, it’s usually a sign of a serious problem like a failing replica or network issue. With RDS, lag is expected and normal—you’re really monitoring how far behind your replicas are and whether it’s acceptable for your use case.
Aurora also provides more visibility into replica health through the Aurora cluster view, showing the status of each replica and whether it’s eligible for promotion. This makes operational decisions (like which replica to promote in a failure scenario) more data-driven.
Conclusion#
Aurora and standard RDS read replicas represent two fundamentally different approaches to scaling reads. Aurora’s shared-storage architecture delivers single-digit millisecond replication lag, supports up to 15 replicas with minimal performance impact on the primary, provides automatic failover with readable replicas, and simplifies operational management through the reader endpoint. This makes Aurora the clear choice for modern, read-heavy workloads requiring consistent performance and operational simplicity.
Standard RDS read replicas trade these operational benefits for explicit control and are better suited to scenarios where replicas primarily serve disaster recovery, cross-region distribution, or workloads tolerant of multi-second replication lag. The traditional binary log replication model is well understood and has decades of operational precedent, which matters if your team has deep existing expertise.
In practice, the choice often comes down to this: if you’re building something new and need multiple read replicas, start with Aurora. If you’re running existing RDS workloads with modest read scaling needs and strong operational practices around RDS, it may continue to work well. But for scaling reads, Aurora’s architecture is simply more efficient and effective, and that efficiency becomes more valuable as your read demands grow.