AWS offers RDS, Aurora, DynamoDB, ElastiCache, and several specialized engines covering relational, NoSQL, caching, time-series, and graph workloads. This page covers how to choose between them and how to use each well.
Why Managed Databases Matter
Running databases yourself means handling backups, patching, replication, failover, and monitoring. AWS managed databases handle all of that, letting you focus on your application instead of database administration.
Consider the following when choosing a database: What type of data will you store? How will you query it? What scale do you need? How important is consistency vs. performance?
Choosing the Right Database
Before diving into specific services, understand the two main categories:
| Category | When to Use | AWS Services |
|---|---|---|
| Relational (SQL) | Structured data, complex queries, transactions | RDS, Aurora |
| NoSQL | Flexible schemas, massive scale, simple queries | DynamoDB, DocumentDB, ElastiCache |
Quick Decision Guide
| Your Situation | Recommended Service |
|---|---|
| Traditional web app with complex queries | RDS (PostgreSQL or MySQL) |
| Need maximum SQL performance | Aurora |
| High-scale with simple key-value access | DynamoDB |
| Need caching layer | ElastiCache (Redis) |
| Document storage (MongoDB compatible) | DocumentDB |
| Time-series data | Timestream |
| Graph relationships | Neptune |
The flowchart below captures the same decision as a series of questions, starting from the shape of your data and access pattern:
flowchart TD
Start([What does your data look like?]) --> Q1{Relational with<br/>JOINs and transactions?}
Q1 -->|Yes| Q2{Need 3-5x throughput<br/>or auto-scaling storage?}
Q2 -->|No| RDS[(RDS<br/>PostgreSQL / MySQL)]
Q2 -->|Yes| Aurora[(Aurora)]
Q1 -->|No| Q3{Access pattern?}
Q3 -->|Key/value at scale| DDB[(DynamoDB)]
Q3 -->|Sub-ms cache| EC[(ElastiCache<br/>Redis)]
Q3 -->|Document / MongoDB| DocDB[(DocumentDB)]
Q3 -->|Graph traversal| Neptune[(Neptune)]
Q3 -->|Time-series| TS[(Timestream)]
Amazon RDS - Managed Relational Databases
RDS runs traditional databases (MySQL, PostgreSQL, MariaDB, Oracle, SQL Server) but handles the operational burden: backups, patching, replication, and failover.
Real-world example: A SaaS application uses RDS PostgreSQL for customer data. RDS automatically backs up the database nightly, replicates to a standby instance for high availability, and can scale up during busy periods.
When to Use RDS
- You need SQL queries with JOINs across tables
- Your data has clear relationships (users, orders, products)
- You need ACID transactions (banking, inventory)
- Your team knows SQL and relational databases
RDS Instance Classes
| Class | Best For | vCPUs | Memory |
|---|---|---|---|
| db.t3 | Development, small workloads | 2-8 | 1-32 GB |
| db.m5 | General production workloads | 2-96 | 8-384 GB |
| db.r5 | Memory-intensive (large datasets) | 2-96 | 16-768 GB |
Amazon Aurora - High-Performance Relational
Aurora is AWS’s cloud-native database, compatible with MySQL and PostgreSQL. It offers up to 5x the throughput of standard MySQL and 3x that of standard PostgreSQL, with automatic storage scaling up to 128 TB.
When to Use Aurora vs RDS
| Factor | RDS | Aurora |
|---|---|---|
| Cost | Lower for small workloads | Better value at scale |
| Performance | Standard | 3-5x faster |
| Storage | Manual provisioning | Auto-scales to 128 TB |
| Replicas | Up to 5 | Up to 15 with faster failover |
| Best for | Dev/test, small production | High-performance production |
Amazon DynamoDB - NoSQL at Scale
DynamoDB is a key-value and document database designed for applications needing consistent single-digit millisecond performance at any scale. It handles millions of requests per second without capacity planning.
Real-world example: A mobile game uses DynamoDB to store player profiles and game state. Whether 100 or 10 million players are online, DynamoDB maintains consistent performance.
When to Use DynamoDB
- Simple access patterns (get item by key, query by partition)
- Massive scale requirements
- Need single-digit millisecond latency
- Schema may evolve over time
When NOT to Use DynamoDB
- Complex queries with multiple JOINs
- Ad-hoc reporting and analytics
- Need for transactions across many items (limited support)
- Team unfamiliar with NoSQL patterns
Amazon ElastiCache - In-Memory Caching
ElastiCache provides Redis and Memcached for caching frequently accessed data. Adding a cache layer can reduce database load by 90% and improve response times from milliseconds to microseconds.
Common Caching Patterns
| Pattern | Use Case | Example |
|---|---|---|
| Cache-aside | Read-heavy workloads | Check cache first, then database |
| Write-through | Need cache consistency | Write to cache and database together |
| Session storage | Web applications | Store user sessions in Redis |
| Rate limiting | API protection | Track request counts per user |
DynamoDB Best Practices
Key Design Principles
DynamoDB works differently from relational databases. Success depends on understanding these principles:
1. Design for your access patterns first: Unlike SQL where you model data then write queries, DynamoDB requires knowing your queries upfront.
2. Use composite keys: Combine partition key (PK) and sort key (SK) to enable efficient queries.
3. Denormalize data: Store related data together. It is okay to duplicate data across items.
Single Table Design
Advanced DynamoDB usage puts all entity types in one table, using different key patterns:
| Entity | PK | SK | Example |
|---|---|---|---|
| User | USER#123 |
PROFILE |
User profile data |
| User’s orders | USER#123 |
ORDER#2024-01-15 |
Order summary |
| Order details | ORDER#456 |
DETAIL |
Full order data |
This enables fetching a user and their recent orders in a single query.
DynamoDB Pricing Models
| Mode | Best For | How It Works |
|---|---|---|
| On-Demand | Variable or unpredictable workloads | Pay per request, no capacity planning |
| Provisioned | Steady, predictable workloads | Set read/write capacity, lower cost |
Start with On-Demand for new applications. Switch to Provisioned once you understand your traffic patterns.
Essential DynamoDB Commands
# Create a table with on-demand billing
aws dynamodb create-table --table-name MyTable \
--attribute-definitions AttributeName=PK,AttributeType=S \
--key-schema AttributeName=PK,KeyType=HASH \
--billing-mode PAY_PER_REQUEST
# Put an item
aws dynamodb put-item --table-name MyTable \
--item '{"PK": {"S": "USER#123"}, "name": {"S": "Alice"}}'
# Query items by partition key
aws dynamodb query --table-name MyTable \
--key-condition-expression "PK = :pk" \
--expression-attribute-values '{":pk": {"S": "USER#123"}}'
Database Selection Summary
| Use Case | Service | Why | Cost Consideration |
|---|---|---|---|
| Traditional web apps | RDS (PostgreSQL/MySQL) | SQL, JOINs, transactions | Pay for instance size |
| High-performance SQL | Aurora | 3-5x faster than RDS | Higher base cost, better at scale |
| Massive scale, simple queries | DynamoDB | Consistent millisecond latency | Pay per request or capacity |
| Caching layer | ElastiCache Redis | Sub-millisecond reads | Pay for node size |
| Time-series (IoT, metrics) | Timestream | Built-in time functions | Pay for writes and queries |
| Graph data (social, fraud) | Neptune | Native graph traversal | Pay for instance size |
| MongoDB workloads | DocumentDB | MongoDB-compatible | Pay for instance size |
Common Patterns
- Web application: RDS/Aurora for main data + ElastiCache for sessions and hot data
- Mobile app: DynamoDB for user data + S3 for media
- Analytics: DynamoDB/RDS for operational data, replicated to S3 for analytics with Athena
Common Pitfalls
- Single-AZ production databases: A non-Multi-AZ RDS instance has no automatic failover. Enable Multi-AZ for any database you cannot afford to lose during a hardware or AZ failure.
- Public database access: Never set
PubliclyAccessible=true. Place databases in private subnets and reach them from application servers or via a bastion / Session Manager. - DynamoDB hot partitions: Concentrating traffic on a single partition key (for example a sequential timestamp) throttles throughput. Choose high-cardinality partition keys that spread load evenly.
- Provisioned capacity for spiky traffic: Provisioned mode throttles requests beyond the set capacity. Use On-Demand until your traffic pattern is well understood, then optimize.
- Caching without an eviction policy: An ElastiCache node with no
maxmemory-policycan fill and fail writes. Setallkeys-lru(or similar) for cache workloads.
Key Takeaways
- Match the model to the access pattern. Use relational (RDS/Aurora) for complex queries and transactions; DynamoDB for massive scale with known key-based access.
- Aurora scales, RDS starts cheap. Use RDS for dev/test and small workloads; move to Aurora when you need 3-5x throughput and storage that auto-grows.
- Design DynamoDB queries first. Unlike SQL, you model the table around access patterns — composite keys and single-table design enable efficient queries.
- Cache to cut load. An ElastiCache (Redis) layer can absorb 90% of read traffic and drop response times to sub-millisecond.
See Also
- AWS Hub - Overview of all AWS documentation
- Compute Services - Lambda with DynamoDB patterns
- Storage Services - S3 for database backups
- Security - Database encryption and access control
- Infrastructure as Code - Database IaC and monitoring
- Database Design Guide - General database concepts