DynamoDB vs RDS: Choosing an AWS Database
The fork you hit most often when picking a database on AWS is DynamoDB versus RDS. The conclusion up front: high-volume, variable-traffic workloads whose access patterns reduce to a fixed handful go to DynamoDB; business data that needs joins, aggregation, and ad-hoc queries goes to RDS. It is not a question of which database is better — it is a question of whether you know your queries now or will decide them later. The RDS-side details (instance classes, whether to use Aurora) are covered in RDS instance classes and Aurora vs RDS. Prices are for us-east-1.
Side-by-side comparison #
| DynamoDB | RDS | |
|---|---|---|
| Data model | Key-value / document | Relational (MySQL, PostgreSQL, etc.) |
| Queries | Key-based lookup + secondary indexes | SQL (joins, aggregation, ad hoc) |
| Schema | Flexible (attributes vary per item) | Fixed (table definitions) |
| Scaling | Automatic horizontal, effectively unlimited | Instance size + read replicas |
| Operations | Serverless (no instances) | Instance management (patching automated) |
| Billing | Per request + storage | Instance hours + storage |
| Idle cost | Approaches zero (on-demand) | Accrues as long as the instance runs |
The model difference: when do you decide your queries #
DynamoDB is the database where access patterns are fixed at table-design time. You fetch items by partition key, slice ranges by sort key, and any other lookup needs a Global Secondary Index (GSI) created in advance. What you get in exchange is freedom to scale: latency stays in single-digit milliseconds at 10x the traffic, partitions grow automatically, and with no concept of an instance, operational overhead is close to zero.
RDS is the database where queries can be decided later. Put data into normalized tables and you can ask anything with joins, aggregation, and subqueries. Reports, admin screens, “this month’s revenue by category” — those requests belong to SQL. The price is a ceiling on scale: writes ultimately lean on scaling up a single instance, and spreading reads means operating replicas.
That difference becomes the working test: “can you enumerate every query you’ll run, today?” Shopping carts, sessions, order processing, IoT events — fixed-pattern workloads fit DynamoDB. Business data whose questions keep changing fits RDS.
Pricing: per request vs per hour #
DynamoDB on-demand bills per request: about $0.625 per million writes and $0.125 per million strongly consistent reads (reflecting the November 2024 50% price cut; eventually consistent reads are half that), with storage at about $0.25 per GB-month (first 25GB free). No traffic means the bill approaches zero, and spikes cost exactly the requests they bring. For steady, predictable traffic, provisioned mode and reserved capacity push unit prices lower — and as covered in RI vs Savings Plans, that reservation is DynamoDB’s own scheme, not a Savings Plan.
RDS bills per instance hour: a db.t4g.micro runs about $12 a month, the production-common db.m8g.large about $123 (single-AZ), plus storage. It is a fixed cost independent of traffic, so the lower the utilization, the worse the effective per-request price.
The crossover math is simple. At a few million requests a month, the DynamoDB bill is a few dollars and there is no contest. At billions of requests a month of steady high traffic, the per-request total starts to overtake the instance fixed cost — that is when you evaluate provisioned mode or re-compare against RDS.
DynamoDB’s traps: they come from both the bill and the design #
- GSIs multiply write costs: every item change replicates to each GSI, so a table with 3 GSIs pays roughly 4x for writes. Indexes created “just in case” multiply the bill.
- Scan is a foul: a full table scan bills for everything read and is slow. Needing scans regularly is the signal that your access-pattern design has broken — and the moment to export data to RDS or an analytics stack.
- Hot partitions: traffic concentrating on one partition key gets throttled even with capacity to spare. Key design is the performance design.
- Transactions cost double: transactional reads and writes bill at 2x. If your domain needs transactions everywhere, revisit whether relational was the right call to begin with.
- The RDS-side trap: combining RDS with a serverless stack (Lambda and friends) brings connection-storm problems that require an extra layer like RDS Proxy. DynamoDB is an HTTP API and has no such issue.
Selection order #
- Start with whether you know your queries: if you can enumerate the access patterns, DynamoDB is a candidate; if “we don’t know what questions will come,” it’s RDS.
- Check join/aggregation/ad-hoc requirements: if reports and admin screens must hit the database directly, RDS is settled. Designs that imitate this on DynamoDB mostly end in regret.
- Look at the traffic pattern: long idle periods or big spikes favor on-demand DynamoDB by billing structure. Steady uniform high traffic gets compared against provisioned mode or RDS.
- Sanity-check write costs including GSIs: item size × writes × (1 + GSI count) is what approximates the real bill.
- Consider running both: the common landing spot is the service path (orders, sessions) on DynamoDB and analytics/reporting on RDS or a warehouse, connected by streams. Nothing requires solving everything with one database.
Summary #
- Fixed access patterns with high, variable traffic: DynamoDB. Joins, aggregation, ad-hoc queries: RDS. “Do you know your queries now?” is the first question.
- The billing structures differ: DynamoDB on-demand is per request (~$0.625 per million writes) with idle cost near zero; RDS is per instance hour, punishing low utilization.
- GSIs multiply write charges and scans signal design failure. DynamoDB cost estimates include GSIs by default.
- Forcing transaction-heavy, evolving business data into DynamoDB is the most common road to regret. The reverse (fixed patterns on RDS) loses on cost and scale.
- Service path on DynamoDB, analytics on relational — the two-database setup is a common right answer. Commitment discounts come from DynamoDB reserved capacity and RDS RIs respectively, not Savings Plans.