Database Options#

AWS offers purpose-built databases for different data models and access patterns:

flowchart TD
    DB["AWS Databases"]
    DB --> Relational["Relational (SQL)"]
    DB --> KV["Key-Value"]
    DB --> Document["Document"]
    DB --> Cache["In-Memory Cache"]
    DB --> Graph["Graph"]
    DB --> TimeSeries["Time Series"]
    
    Relational --> RDS["RDS / Aurora"]
    KV --> DDB["DynamoDB"]
    Document --> DocDB["DocumentDB"]
    Cache --> EC["ElastiCache"]
    Graph --> Neptune["Neptune"]
    TimeSeries --> TS["Timestream"]

RDS (Relational Database Service)#

Managed relational databases — AWS handles patching, backups, failover, and replication.

Supported Engines#

EngineUse Case
PostgreSQLGeneral purpose, complex queries, JSON support
MySQLWeb applications, WordPress, simple schemas
MariaDBMySQL-compatible, community-driven
OracleEnterprise, legacy applications
SQL Server.NET applications, Microsoft ecosystem
AuroraAWS-native, MySQL/PostgreSQL compatible, 5x performance

RDS Architecture#

flowchart TD
    App["Application"] --> Primary["RDS Primary<br>(AZ 1a)"]
    Primary -->|"Synchronous<br>replication"| Standby["RDS Standby<br>(AZ 1b)"]
    Primary -->|"Async<br>replication"| Read1["Read Replica 1"]
    Primary -->|"Async<br>replication"| Read2["Read Replica 2"]
    
    App -->|"Read queries"| Read1
    App -->|"Read queries"| Read2

Multi-AZ vs Read Replicas#

FeatureMulti-AZRead Replica
PurposeHigh availabilityRead scaling
ReplicationSynchronousAsynchronous
FailoverAutomatic (< 2 min)Manual promotion
AccessibleNo (standby only)Yes (read traffic)
Cross-regionNoYes

RDS Backups#

  • Automated backups — daily snapshots + transaction logs (point-in-time recovery)
  • Retention — 1-35 days
  • Manual snapshots — persist until you delete them
  • Cross-region — copy snapshots to another region for DR

Aurora#

AWS’s cloud-native relational database — MySQL and PostgreSQL compatible but with significant architectural improvements:

flowchart TD
    subgraph Compute["Compute Layer"]
        Writer["Writer Instance"]
        Reader1["Reader Instance 1"]
        Reader2["Reader Instance 2"]
    end
    
    subgraph Storage["Storage Layer (shared, distributed)"]
        S1["Copy 1<br>AZ-a"]
        S2["Copy 2<br>AZ-a"]
        S3["Copy 3<br>AZ-b"]
        S4["Copy 4<br>AZ-b"]
        S5["Copy 5<br>AZ-c"]
        S6["Copy 6<br>AZ-c"]
    end
    
    Writer --> Storage
    Reader1 --> Storage
    Reader2 --> Storage
FeatureStandard RDSAurora
StorageSingle EBS volumeDistributed across 3 AZs (6 copies)
Failover1-2 minutes< 30 seconds
Read replicasUp to 5Up to 15
Storage scalingManualAuto (up to 128 TB)
PerformanceBaseline5x MySQL, 3x PostgreSQL

Aurora Serverless#

Automatically scales compute capacity based on demand:

No traffic → 0 ACUs (paused, no cost)
Light traffic → 2 ACUs
Heavy traffic → 64 ACUs

Ideal for: infrequent workloads, dev/test, variable traffic.


DynamoDB#

Fully managed NoSQL key-value and document database. Single-digit millisecond latency at any scale.

Data Model#

Table: Orders
├── Partition Key: customer_id (String)
├── Sort Key: order_date (String)
└── Attributes: items, total, status (flexible schema)
ConceptDescription
TableCollection of items
ItemA single record (like a row)
AttributeA field on an item (like a column)
Partition KeyPrimary key for distribution
Sort KeyOptional, enables range queries
GSIGlobal Secondary Index (query on non-key attributes)

Capacity Modes#

ModeBillingBest For
On-DemandPer requestUnpredictable traffic
ProvisionedPer RCU/WCUPredictable, steady traffic

DynamoDB Strengths and Limitations#

StrengthLimitation
Single-digit ms latencyNo complex joins
Infinite scaleQuery patterns must be designed upfront
Fully managedMax item size: 400 KB
Global tables (multi-region)Eventual consistency by default
TTL (auto-delete expired items)Limited aggregation

ElastiCache#

Managed in-memory data stores for microsecond latency:

EngineUse Case
RedisCaching, sessions, leaderboards, pub/sub, queues
MemcachedSimple caching, multi-threaded

Caching Pattern#

sequenceDiagram
    participant App
    participant Cache as ElastiCache
    participant DB as RDS
    
    App->>Cache: GET user:123
    alt Cache Hit
        Cache-->>App: Return cached data
    else Cache Miss
        Cache-->>App: null
        App->>DB: SELECT * FROM users WHERE id=123
        DB-->>App: User data
        App->>Cache: SET user:123 (TTL: 300s)
    end

Choosing a Database#

NeedServiceWhy
Complex queries, joins, transactionsRDS/AuroraSQL, ACID compliance
High-performance relationalAurora5x MySQL performance
Key-value at scaleDynamoDBInfinite scale, ms latency
Caching layerElastiCache RedisMicrosecond reads
Full-text searchOpenSearchElasticsearch-compatible
Graph relationshipsNeptuneTraversal queries
Time-series dataTimestreamIoT, metrics, events

Key Takeaways#

  1. Aurora over standard RDS — better performance, availability, and auto-scaling storage
  2. DynamoDB for scale — infinite throughput, but design access patterns upfront
  3. Multi-AZ for production — automatic failover protects against AZ failure
  4. Read replicas for read-heavy — offload reads, reduce primary load
  5. ElastiCache in front of databases — reduce latency and database load
  6. Automated backups always — enable point-in-time recovery
  7. Choose the right tool — don’t force SQL for key-value or NoSQL for complex joins