AWS Aurora vs DynamoDB vs RDS: Which Database Should You Choose?
Compare AWS RDS, Aurora, and DynamoDB across performance, scalability, pricing, consistency, and use cases. A comprehensive guide to choosing the right AWS database service for your architecture.
Amazon Web Services offers over a dozen database services, but three stand out as the most commonly evaluated: Amazon RDS, Amazon Aurora, and Amazon DynamoDB. Each serves a distinct purpose, yet architects frequently struggle to pick the right one for a given workload. RDS provides familiar managed relational databases. Aurora reimagines relational storage for the cloud with dramatic performance gains. DynamoDB delivers serverless NoSQL at virtually any scale. Understanding their differences in data model, consistency, scaling, pricing, and operational complexity is essential before committing to an architecture. This guide offers a detailed, research-backed comparison to help you decide.
Introduction
Choosing the right database on AWS is not a one-size-fits-all decision. Each service optimizes for different trade-offs. Amazon RDS (Relational Database Service) is the safest choice if your team is already familiar with traditional relational databases like MySQL, PostgreSQL, or SQL Server. It abstracts hardware provisioning, patching, backups, and failover, but still exposes a familiar SQL interface. Amazon Aurora is AWS's proprietary relational engine, backward-compatible with MySQL and PostgreSQL, but engineered from the ground up for the cloud. It delivers 5x the throughput of standard MySQL and 3x the throughput of standard PostgreSQL, with storage that auto-scales from 10 TiB to 128 TiB. Amazon DynamoDB is a fully managed NoSQL key-value and document database designed for single-digit-millisecond latency at any scale. It powers some of the world's largest applications at Amazon, Netflix, Airbnb, and Lyft. This article examines each service across every meaningful dimension so you can map your workload requirements to the right database.
Amazon RDS: The Managed Relational Workhorse
Amazon RDS is the most direct path to running a relational database in the cloud without managing the underlying operating system or database software. It supports six database engines: MySQL, PostgreSQL, MariaDB, Oracle Database, Microsoft SQL Server, and the Amazon-specific Amazon RDS on VMware. Key capabilities include automated backups with point-in-time recovery, automated patch management, Multi-AZ deployments for high availability, and read replicas for offloading read traffic. RDS offers three storage types: General Purpose (gp2/gp3) SSDs, Provisioned IOPS (io1/io2) for latency-sensitive OLTP workloads, and magnetic storage for legacy compatibility. With Provisioned IOPS, you can allocate up to 256,000 IOPS per instance on io2 volumes, though typical production workloads run between 5,000 and 80,000 IOPS. RDS uses standard hourly instance pricing plus storage and I/O charges, making costs predictable but potentially high for bursty or spiky workloads. It is best suited for traditional enterprise applications, content management systems (CMS), ERP systems, and any workload that benefits from a mature relational toolchain.
Amazon Aurora: Cloud-Native Relational Engine
Amazon Aurora is not a fork of MySQL or PostgreSQL but a completely new distributed storage engine designed to be wire-compatible with both. Where RDS separates compute from storage conceptually, Aurora fully decouples them at the architectural level. Storage is implemented as a multi-tenant, fault-tolerant, auto-healing volume striped across hundreds of SSDs in three Availability Zones. This gives Aurora several unique advantages. First, storage auto-scales from 10 TiB to 128 TiB in 10 GiB increments with no downtime and no repartitioning. Second, Aurora achieves up to 200,000 IOPS against the cluster volume, far exceeding typical RDS Provisioned IOPS limits. Third, Aurora replicates data six ways across three AZs (two copies per AZ) with no impact on write latency. Fourth, in the event of a database crash, Aurora recovers in about 60 seconds regardless of database size, compared to hours for traditional MySQL. Fifth, an Aurora cluster supports up to 15 low-latency read replicas (compared to RDS's 5 for MySQL and 5 for PostgreSQL), and replica lag is typically under 100 milliseconds. Aurora also offers Global Database, which replicates data to up to five secondary regions with typical RPO of 1 second and failover in under a minute. AWS reports that Aurora can reduce database costs to as low as one-tenth the cost of commercial databases while providing better performance. Aurora is the go-to choice for high-performance relational workloads, SaaS platforms, financial applications, and any environment where downtime is unacceptable.
Amazon DynamoDB: NoSQL at Scale
Amazon DynamoDB is AWS's flagship NoSQL database, purpose-built for applications that need consistent single-digit-millisecond response times at any scale. It supports both key-value and document data models with JSON-like nested attributes. DynamoDB is fully serverless: there are no servers to provision, no software to patch, and no clusters to manage. Capacity can be configured as provisioned (with auto-scaling) or on-demand, where the database scales instantly to handle millions of requests per second without manual intervention. The DynamoDB Accelerator (DAX) is an in-memory cache that reduces response times to microseconds for read-heavy workloads. DynamoDB Transactions provide ACID guarantees across up to 25 items or 4 MB of data within a single region. DynamoDB Streams capture item-level changes in near real-time, enabling event-driven architectures with AWS Lambda. For multi-region use, DynamoDB Global Tables offer active-active replication across any number of AWS Regions, with conflict resolution based on last-writer-wins semantics. DynamoDB is the engine behind Amazon.com's shopping cart, Netflix's session store, and Lyft's ride-matching platform. It excels in real-time web applications, gaming leaderboards, IoT telemetry ingestion, session management, and any workload that demands elastic scalability without operational overhead. However, DynamoDB is not designed for complex joins, ad-hoc analytical queries, or workloads requiring fine-grained relational constraints.
AWS Database Comparison Table
| Dimension | Amazon RDS | Amazon Aurora | Amazon DynamoDB |
|---|---|---|---|
| Data Model | Relational (SQL) — tables, rows, joins, foreign keys | Relational (SQL) — MySQL/PostgreSQL wire-compatible | NoSQL key-value and document — JSON items, partition + sort keys |
| Database Engines | MySQL, PostgreSQL, MariaDB, Oracle, SQL Server | Aurora MySQL, Aurora PostgreSQL (custom storage engine) | Proprietary NoSQL engine |
| Performance | Up to ~5,000 IOPS (gp3 baseline) or ~256,000 IOPS (io2 provisioned) | Up to ~200,000 IOPS against cluster volume; 5x MySQL / 3x PostgreSQL throughput | Single-digit-millisecond latency P99 at any scale; DAX for microsecond reads |
| Consistency | Strong consistency (ACID) within a single database; eventually consistent read replicas | Eventual consistency for read replicas; strong consistency for cluster writes | Strongly consistent reads optional; eventually consistent reads by default; transactions for multi-item ACID |
| Scaling | Vertical: larger instance sizes; read replicas (5 per engine); some storage scaling | Auto-scaling storage (10 TiB–128 TiB); up to 15 low-latency read replicas; compute scaling via instance size | Horizontal auto-sharding via partition key; auto-scaling RCU/WCU or on-demand; essentially unlimited throughput |
| Pricing Model | Hourly instance + provisioned storage + I/O; reserved instances available | Hourly compute + storage (GB/month) + I/O (reads/writes); reserved instances | Per RCU/WCU (provisioned or on-demand) + storage (GB/month) + data transfer; reserved capacity available |
| ACID / Transactions | Full ACID across multiple tables and rows | Full ACID — compatible with MySQL/PostgreSQL transaction semantics | Single-item ACID; multi-item transactions across up to 25 items or 4 MB |
| High Availability | Multi-AZ with synchronous standby replica; failover ~60–120 seconds | Six copies across 3 AZs; crash recovery ~60 seconds regardless of DB size | Built-in multi-AZ replication; data is automatically replicated across 3 AZs |
| Global Replication | Cross-region read replicas (asynchronous) | Aurora Global Database: up to 5 secondary regions, RPO of 1 second | Global Tables: active-active multi-region, last-writer-wins conflict resolution |
| Typical Use Cases | Traditional enterprise apps, ERP, CMS, e-commerce backends, legacy migrations | High-performance SaaS, financial systems, e-commerce, CRM, any MySQL/PostgreSQL workload at scale | Real-time web apps, gaming, IoT, session store, ad tech, leaderboards, cache |
Performance and Scalability
Performance characteristics differ dramatically across these three services. Amazon RDS provides predictable IOPS tied to the chosen instance type and storage volume. With gp3 volumes you get a baseline of 3,000 IOPS and can burst to 16,000 IOPS for small volumes. For workloads that need consistent sub-millisecond latency, io2 Block Express volumes deliver up to 256,000 IOPS at 99.999% durability. However, scaling RDS requires manual intervention: you must modify the instance class (vertical scaling) or add read replicas, which may lag behind the primary. RDS for MySQL and PostgreSQL support up to 5 read replicas each.
Amazon Aurora redefines relational performance by decoupling storage from compute. The cluster volume delivers up to 200,000 IOPS, and the distributed storage layer handles replication, backup, and recovery without consuming compute resources. AWS benchmarks show Aurora MySQL delivering 5x the throughput of standard MySQL and Aurora PostgreSQL delivering 3x the throughput of standard PostgreSQL for the same instance class. Aurora read replicas are "cluster endpoints" that can serve read traffic with minimal replica lag, typically under 100 milliseconds. The service supports up to 15 Aurora Replicas, far exceeding RDS's limit. Scaling Aurora is largely automatic for storage; for compute, you can adjust instance size or provision an Aurora Serverless v2 endpoint that auto-scales based on load.
Amazon DynamoDB operates on a fundamentally different scaling model. Throughput is defined in Read Capacity Units (RCUs) and Write Capacity Units (WCUs), each representing a single strongly consistent read of 4 KB or a write of 1 KB per second. The on-demand capacity mode eliminates capacity planning entirely: DynamoDB scales instantly to accommodate traffic spikes. For provisioned mode, auto-scaling adjusts RCU/WCU based on target utilization. DynamoDB achieves single-digit-millisecond P99 latency regardless of table size. For read-heavy workloads, adding a DAX cluster reduces response times to microseconds. DynamoDB's horizontal partitioning means throughput is effectively unlimited: just increase your partition key cardinality and add capacity. A single DynamoDB table has no practical throughput cap.
Pricing Models Compared
RDS pricing is straightforward but can add up. You pay per hour for the instance based on class (db.m7g.large at roughly $0.17/hr, db.r7g.8xlarge at roughly $2.79/hr). Storage costs $0.08/GB-month for gp3, $0.125/GB-month for io2, plus I/O charges of $0.005 per million I/O requests. Reserved instances can reduce costs by 30–60%. Multi-AZ doubles compute and storage costs. At moderate scale, RDS costs are predictable but not cheap.
Aurora pricing separates compute and storage. Compute costs $0.04–$0.12 per hour per ACU (Aurora Capacity Unit), depending on instance class. Storage is billed at $0.10/GB-month for the cluster volume consumed, and I/O reads/writes are billed at $0.20 per million requests. Aurora's storage is compressed automatically, often reducing storage footprint by 30–50% compared to RDS. For I/O-heavy workloads, Aurora can be significantly cheaper than RDS because it only charges for actual I/O operations rather than provisioned IOPS. AWS claims Aurora can be up to 7x less expensive than commercial databases and often cheaper than RDS MySQL/PostgreSQL at scale because fewer replicas are needed and storage is more efficient.
DynamoDB pricing is consumption-based. For provisioned capacity, an RCU costs $0.00013 per hour and a WCU costs $0.00065 per hour. On-demand capacity is $1.25 per million writes and $0.25 per million reads (or $0.50 with strong consistency). Storage is $0.25/GB-month plus $0.02 per million read/write request units for DynamoDB Streams and DAX. On-demand is ideal for unpredictable workloads but can be expensive for sustained traffic. For example, an application doing 10,000 writes per second with on-demand would cost roughly $21,600/month in write capacity alone. Reserved capacity (one-year or three-year terms) can cut costs by up to 50% for predictable workloads. DynamoDB is cost-effective at massive scale because it eliminates idle capacity, but it requires careful capacity planning to avoid surprise bills.
Migration Paths Between Services
Migrating between these database services varies from trivial to architecturally significant. Moving from RDS to Aurora is the smoothest path. AWS provides a "migrate with zero downtime" feature that converts an RDS MySQL or PostgreSQL snapshot into an Aurora cluster. You can also use the AWS Database Migration Service (DMS) for ongoing replication with minimal cutover downtime — typically 60 seconds. The schema remains identical, application code usually requires no changes, and the endpoint string is updated during cutover. AWS also supports migrating from an external MySQL or PostgreSQL database directly to Aurora via DMS or a pg_dump/mysqldump import.
Migrating from RDS or Aurora to DynamoDB is a more involved process because the data models are fundamentally different. A relational schema with normalized tables, foreign keys, joins, and transactions must be redesigned as a denormalized NoSQL schema. Typically you create a single DynamoDB table (or a small number of tables) with a well-chosen partition key and sort key to support all access patterns. DMS can migrate data from RDS to DynamoDB by reading the relational tables and writing items into DynamoDB. However, application code must be rewritten from SQL queries to DynamoDB API calls (GetItem, Query, Scan, PutItem, UpdateItem). This is a significant engineering effort but often worthwhile for workloads that need DynamoDB's elastic scalability. AWS offers a DynamoDB schema conversion tool as part of the DMS console to assist with schema redesign.
For Aurora to RDS or DynamoDB to RDS/Aurora, the same principles apply in reverse. DynamoDB exports to Amazon S3 (in DynamoDB JSON format) can be loaded into Aurora or RDS via AWS Glue or ETL pipelines, but the denormalized data must be restructured into normalized relational tables. In general, moving from NoSQL to relational requires more effort than the reverse direction.
Multi-Region and Global Deployments
Global applications require database replication across AWS Regions. Each service provides a different approach. RDS supports cross-region read replicas with asynchronous replication. For MySQL and MariaDB, replica lag is typically under one second in the same region but can exceed five seconds across regions. Write operations are performed on the primary region only; the replicas are read-only. Failover requires manual promotion of a read replica to a primary instance, which takes from one to several minutes.
Aurora Global Database is a purpose-built replication feature that spans up to five secondary AWS Regions. Replication is dedicated and does not impact primary cluster performance. The Recovery Point Objective (RPO) is typically one second or less, and failover can be completed in under one minute. Aurora Global Database is ideal for disaster recovery and low-latency global reads. It is not active-active — writes are accepted only on the primary region, though secondary regions can be promoted to primary during failover.
DynamoDB Global Tables provide active-active multi-region replication. Any region in the global table can handle both reads and writes, with conflict resolution via last-writer-wins (based on AWS CloudTrail timestamps). Replication is typically completed within seconds. Global Tables are multi-master by design and require no manual failover. This makes them well-suited for globally distributed applications that need low-latency writes everywhere — for example, a globally deployed gaming platform or an ad-serving network. The trade-off is eventual consistency across regions; strongly consistent reads are only available within a single region.
Common Architecture Patterns
Production architectures frequently combine these services rather than relying on a single database. Three patterns are particularly common.
Aurora for OLTP + DynamoDB for caching/sessions. Aurora serves as the primary operational data store for transactional workloads — orders, invoices, user profiles — while DynamoDB handles high-throughput, low-latency access to session state and cached data. This pattern is common in e-commerce platforms. DynamoDB's DAX cache sits between the application and DynamoDB for sub-millisecond session lookups, and Aurora's ACID transactions ensure order integrity.
Aurora for reads + DynamoDB for writes (CQRS). In a Command Query Responsibility Segregation architecture, write operations are directed to DynamoDB for maximum ingestion throughput, and a background process (such as DynamoDB Streams triggering a Lambda function) replicates the data into Aurora for complex relational queries and reporting. This pattern suits applications with high write velocity — IoT telemetry, ad impression logs, or real-time analytics — where the query side benefits from SQL-based aggregation and joins.
RDS as a reporting replica of Aurora. Some teams use Aurora for production OLTP and spin up an RDS MySQL or PostgreSQL instance as a reporting replica using binary log replication. The RDS replica handles heavy analytical queries without impacting Aurora's transactional performance. While this adds some operational complexity, it keeps reporting workloads isolated from the primary database.
For serverless applications, DynamoDB integrated with AWS Lambda and API Gateway provides a fully serverless backend with no database infrastructure to manage. Aurora Serverless v2 offers a relational option within a serverless architecture, scaling compute capacity automatically from 0.5 to 128 ACUs.
Decision Framework and FAQs
When choosing between RDS, Aurora, and DynamoDB, start with your data model. If your data is highly relational with complex joins, foreign keys, and transactions, use RDS or Aurora. Choose RDS if your team's expertise is with a specific engine (Oracle, SQL Server) or if you need a simple, proven managed service. Choose Aurora if you need higher throughput, faster scaling, lower latency, or lower cost at scale — Aurora almost always beats RDS on performance per dollar for MySQL and PostgreSQL workloads.
Choose DynamoDB if your access patterns are key-value lookups or simple queries, you need single-digit-millisecond latency at any scale, you want a fully serverless experience, or your workload is unpredictable and benefits from on-demand scaling. Avoid DynamoDB if you need complex relational queries, multi-table joins, or referential integrity.
Frequently Asked Questions
Can I use both Aurora and DynamoDB in the same application? Yes. This is a common and recommended pattern. Use Aurora for transactional data (orders, accounts, inventory) and DynamoDB for high-speed lookups, sessions, and real-time data (shopping carts, user preferences, leaderboards).
Is Aurora always cheaper than RDS? Not always. At small scale (single db.t4g instance, low storage), RDS can be cheaper because Aurora charges for I/O operations and storage separately. As storage and throughput grow, Aurora's automatic compression and efficient storage model typically make it more cost-effective than equivalent RDS configurations.
Does DynamoDB support SQL? DynamoDB does not support SQL natively. You query data using the DynamoDB API (GetItem, Query, Scan) or PartiQL, a SQL-compatible query language that DynamoDB supports. PartiQL can handle simple SELECT, INSERT, UPDATE, and DELETE operations but does not support JOINs or complex aggregations.
When should I use DynamoDB on-demand vs provisioned capacity? Use on-demand for new applications with unknown traffic patterns, spiky workloads, or development and testing environments. Use provisioned capacity (with auto-scaling) for predictable production workloads where you can estimate baseline traffic, as it is significantly cheaper for sustained usage.
Can RDS Multi-AZ be used for read scaling? No. RDS Multi-AZ maintains a standby replica in another Availability Zone for automatic failover only. The standby cannot serve read traffic. To scale reads, you must create separate read replicas (up to 5 per engine). In contrast, all Aurora Replicas in an Aurora cluster can serve read traffic, and the cluster automatically fails over to one of them.
For further reading, consult the official Amazon RDS documentation, Amazon Aurora documentation, and Amazon DynamoDB documentation for the latest benchmarks, pricing, and feature updates. The AWS Database Migration Service provides tools for schema conversion and live migration between these services.
This article is for informational purposes only and does not constitute professional advice. Always consult a qualified professional for specific guidance related to your situation.