RDS vs DynamoDB in AWS
The choice between RDS and DynamoDB is not a preference — it’s a structural decision that shapes your data model, access patterns, and scaling behavior. The wrong choice leads to either a schema that fights your queries or a database that becomes a bottleneck at scale.
The fundamental difference
RDS (PostgreSQL, MySQL, and others) is a relational database. Data is organized in tables with defined schemas — columns have types, foreign keys enforce relationships, and constraints maintain integrity. You query it with SQL, which lets you ask any question about any combination of columns. The database figures out how to execute the query. You don’t need to know your queries at design time.
DynamoDB is a key-value and document store. Each item has a primary key (partition key, optionally combined with a sort key). You retrieve items by their key. Secondary indexes (Global Secondary Indexes and Local Secondary Indexes) let you query by other attributes — but you must create those indexes at design time. If a user asks for data in a way you didn’t anticipate when designing your table, you may have to scan the entire table (slow and expensive) or restructure your data model.
This difference is profound: SQL databases are flexible by default; DynamoDB is fast by default. You trade query flexibility for performance guarantees.
RDS vs DynamoDB comparison
| Dimension | RDS (PostgreSQL/MySQL) | DynamoDB |
|---|---|---|
| Data model | Tables with fixed schema, rows and columns | Key-value and document, flexible attributes per item |
| Query language | SQL — any ad-hoc query | Key-based queries and secondary indexes — must be designed upfront |
| Scaling model | Vertical (bigger instance) + read replicas | Horizontal — scales automatically, effectively unlimited |
| Performance at scale | Degrades under heavy load; requires tuning | Single-digit millisecond at any scale — guaranteed |
| Consistency model | ACID transactions (strong consistency) | Eventually consistent by default; strong consistency available |
| Schema flexibility | Fixed schema — migrations required to change structure | No schema — each item can have different attributes |
| Joins | Full SQL JOIN support | No joins — design your data to avoid them |
| Pricing model | Per hour for instance + storage | Per read/write unit consumed + storage |
| Managed maintenance | AWS handles patches, backups; minor version manual | Fully managed — no maintenance windows |
When RDS is the right choice
Complex data relationships. If your data model has many-to-many relationships, hierarchical data with multiple levels, or requires joins across multiple tables, RDS is the natural fit. A SaaS application with users, organizations, subscriptions, invoices, and audit logs — with foreign keys connecting them — is a relational schema. Fighting that into DynamoDB’s single-table design requires significant effort and expertise.
Existing SQL codebase. If you’re migrating an application from on-premises to AWS, and it uses PostgreSQL or MySQL, moving to RDS requires changing almost nothing about your database code. Moving to DynamoDB requires redesigning your data model from scratch.
Ad-hoc queries and reporting. If your application needs reporting queries — “show me all orders from customers in California who bought more than $500 last month” — SQL handles this naturally. DynamoDB would require a Global Secondary Index on every column you might filter by, and even then, complex multi-condition queries require scanning.
ACID transactions across tables. If you need to update multiple related records atomically — charge a customer’s balance and create an order record in the same transaction, rolling back if either fails — PostgreSQL’s transaction model is clean and reliable. DynamoDB transactions work but are more constrained.
Development teams that know SQL. SQL is one of the most widely known query languages. Almost every developer knows it. DynamoDB’s single-table design patterns (combining entities in one table with compound sort keys) require specific NoSQL design knowledge that’s less universally understood.
See RDS overview for instance sizing, backup configuration, and read replica setup.
When DynamoDB is the right choice
Extreme scale with simple access patterns. If you need to store and retrieve hundreds of millions or billions of items with consistent sub-10ms response time, DynamoDB delivers this without configuration. RDS requires significant tuning, sharding, and read replica management at that scale. If you know your queries — “get this user’s session by session ID,” “get all orders for this customer ID” — DynamoDB handles them with single-millisecond performance at any scale.
User sessions and authentication state. Session data is a perfect DynamoDB use case: retrieve session by ID, set a TTL for automatic expiration, write once and read many times. There are no joins. The access pattern is fixed. DynamoDB’s TTL feature deletes expired items automatically.
IoT data and time-series events. High-volume, high-velocity write workloads — device telemetry, clickstream data, game events — require write performance that relational databases struggle with. DynamoDB can ingest millions of writes per second with consistent latency.
Gaming leaderboards. A leaderboard is a classic DynamoDB use case: sort key on score, query the top N players by partition key (game ID) with a sort key condition. Fast, scalable, and the access pattern is known at design time.
Serverless and pay-per-use architectures. DynamoDB On-Demand pricing charges per read/write request. At low volume, the cost is negligible. For applications that have irregular traffic — an internal tool, a low-traffic API, a development database — you pay nothing during idle periods. RDS charges by the hour regardless of traffic.
The access pattern design requirement
DynamoDB’s biggest hidden cost for new users is the requirement to design your data model around your queries before writing a line of code.
In RDS, you design a normalized schema — users table, orders table, products table — and write SQL queries against it. If requirements change and you need a new query, you write a new SQL query. Maybe you add an index for performance.
In DynamoDB, you need to know your access patterns upfront:
- “Get user by user ID”
- “Get all orders for a user, sorted by date”
- “Get order by order ID”
- “Get all orders with status PENDING”
Each distinct access pattern requires a primary key design or Global Secondary Index that supports it. Getting this wrong means expensive table scans or an application that can’t answer queries it needs to.
DynamoDB’s single-table design pattern (putting multiple entity types in one table, using a partition key like USER#userId and sort keys like ORDER#orderId) is powerful but requires NoSQL design experience. Most teams underestimate this.
If your team doesn’t have NoSQL design experience and your schema has more than 3-4 entity types with relationships, start with RDS. DynamoDB’s performance advantages don’t matter if your data model is wrong.
Cost comparison at different scales
Low volume (development, internal tools):
- RDS db.t3.micro: $0.017/hr = ~$12/month + storage
- DynamoDB On-Demand: essentially free at low request volume
Medium volume (1 million reads + 1 million writes per day):
- RDS db.t3.medium: ~$50/month — handles this comfortably
- DynamoDB On-Demand: ~1M reads × $0.25/million + 1M writes × $1.25/million = ~$1.50/day = ~$45/month
At medium scale, costs are comparable. DynamoDB’s advantage is elasticity — it handles a 10x traffic spike without configuration.
High volume (1 billion reads per day):
- RDS requires significant vertical scaling, read replicas, and potentially sharding — easily $500–2000+/month
- DynamoDB On-Demand: 1B × $0.25/million = $250/day (expensive — but consistent)
- DynamoDB Provisioned with Auto Scaling: can be significantly cheaper with steady traffic
At very high read volume, DynamoDB requires capacity planning to be cost-effective.
Quick decision guide
- Choose RDS if: your data has complex relationships, you need ad-hoc query flexibility, your team knows SQL and not NoSQL design, or you’re migrating an existing relational application.
- Choose DynamoDB if: you have simple, known access patterns; need single-digit millisecond performance at any scale; are storing sessions/events/IoT data; or want serverless pay-per-use pricing.
- DynamoDB requires designing your data model around your queries upfront — underestimate this at your own risk. If your access patterns aren’t clear, use RDS.
- Both are AWS managed services with automated backups — neither requires OS management or database patching.
Frequently asked questions
What is the main difference between RDS and DynamoDB?
RDS is a managed relational database service (PostgreSQL, MySQL, Oracle, SQL Server, MariaDB). It uses SQL, has a fixed schema, supports complex queries and joins, and provides ACID transactions. DynamoDB is a managed NoSQL key-value and document store. It has a flexible schema, requires you to design access patterns upfront, scales to any volume automatically, and delivers single-digit millisecond performance at any scale.
Can I run ad-hoc queries on DynamoDB?
DynamoDB supports queries only by primary key (partition key + optional sort key) and secondary indexes (GSIs and LSIs). Ad-hoc queries over arbitrary attributes require scanning the entire table, which is slow and expensive. If your application needs ad-hoc query flexibility — for example, reporting on any column combination — RDS is the better fit. DynamoDB is designed for known, predictable access patterns.
Does DynamoDB support transactions?
Yes. DynamoDB Transactions (TransactWriteItems and TransactGetItems) support ACID transactions across multiple items in the same or different tables. However, they are more limited than relational transactions — they don't support complex multi-table joins or SQL-style procedural logic. For complex multi-table transactional workflows, RDS is still the better choice.