Development with AWS Services · Topic 5 of 7
Choosing Data Stores and Caching
Pick DynamoDB, RDS, Aurora, S3, ElastiCache or OpenSearch by access pattern, then choose lazy loading, write-through, DAX or ElastiCache to cache it.
- 5 min
- Choose the store from the access pattern, not from habit.
- DynamoDB suits key based access; RDS and Aurora suit joins and SQL.
- Put large objects in S3 and keep pointers in the database.
What it is
No single AWS data store fits every job. You choose by access pattern: how the application reads and writes data, how fast, how big, and how it asks questions.
A cache keeps copies of hot data in fast memory so repeated reads skip the slower store. It lowers latency and protects the database. The right cache depends on which data store sits behind it.
How it works
Matching the store to the access pattern
| Access pattern | Best fit | Why |
|---|---|---|
| Lookup by known key at any scale, single digit millisecond | Amazon DynamoDB | Key value and document model, serverless scaling |
| Joins, ad hoc SQL, multi row transactions | Amazon RDS or Aurora | Relational engine with SQL |
| Large files, images, backups, static content | Amazon S3 | Object storage with very large capacity |
| Very hot reads, sessions, counters, leaderboards | Amazon ElastiCache | In memory, sub millisecond |
| Full text search and log search | Amazon OpenSearch Service | Search and analytics engine |
| SQL over files already in S3 | Amazon Athena | Queries data in place |
| Shared file system for many instances | Amazon EFS | NFS file storage |
Some rules of thumb help with scenario questions.
- If every query names the key, DynamoDB fits. If the questions are unpredictable or need joins, a relational database fits better.
- A DynamoDB item is limited to 400 KB. Keep large objects in S3 and store the S3 key in the item.
- A single S3 PUT handles up to 5 GB. For bigger objects, and for large uploads in general, use multipart upload.
- Aurora is a MySQL and PostgreSQL compatible relational engine and is chosen when RDS needs higher performance and availability.
Caching strategies
Lazy loading (also called cache aside) is the common pattern. The application checks the cache, and on a miss it reads the database and writes the result to the cache with a TTL.
def get_product(pid):
item = cache.get(pid)
if item is None: # cache miss
item = db.get(pid)
cache.set(pid, item, ex=300) # expire after 300 seconds
return item
Only requested data is cached, so a node failure is not fatal. The first read after a miss is slower, and data can be stale until the TTL ends.
Write-through updates the cache every time the database is written. Data stays fresh, but you cache items that may never be read and every write costs more.
A TTL bounds staleness in both patterns. A short TTL gives fresher data and a lower hit rate.
Which cache for which store
| Data store | Cache | Notes |
|---|---|---|
| DynamoDB | DAX (DynamoDB Accelerator) | A cluster in your VPC that speaks the DynamoDB API, so you swap the client and keep your code |
| RDS or Aurora | ElastiCache | You write the lazy loading logic in the application |
| S3 or website content | CloudFront | Caches at edge locations |
| API responses | API Gateway cache | Per stage, with a TTL |
DAX has an item cache for GetItem and BatchGetItem, and a query cache for Query and Scan. Writes go through DAX to the table. The default item cache TTL is 5 minutes.
DAX caches only eventually consistent reads. A strongly consistent read passes through to DynamoDB and is not cached, so an application that needs those reads gets little help from DAX.
ElastiCache runs two engine families. Valkey and Redis OSS offer rich data structures, replication, snapshots and pub/sub, which suits session stores and leaderboards. Memcached is a simple, multithreaded key value cache without replication or persistence.
How the exam asks about this
- "A read heavy DynamoDB table needs microsecond reads with the least code change." -> DAX.
- "Complex SQL results are read repeatedly and the RDS instance is overloaded." -> ElastiCache with lazy loading in the application.
- "Users upload 2 GB videos that must be stored cheaply and served later." -> Amazon S3 with multipart upload.
What to remember for the exam
- Choose the store from the access pattern, not from habit.
- DynamoDB suits key based access; RDS and Aurora suit joins and SQL.
- Put large objects in S3 and keep pointers in the database.
- Lazy loading caches only what is read; write-through keeps the cache fresh.
- DAX is the drop in cache for DynamoDB; ElastiCache fronts relational stores.
- DAX does not cache strongly consistent reads.
- Valkey and Redis OSS add replication and structures; Memcached is simple and multithreaded.
A cache never replaces the database. Treat the data store as the source of truth, and set a TTL so that stale entries expire.
Common mistakes
Using DAX for a write heavy workload. DAX helps repeated reads. Writes still go to the table, so a write bound table gains little.
Caching without a TTL. Entries then stay until evicted, and users see stale data after updates.
Putting binary blobs in DynamoDB. The 400 KB item limit and capacity costs point to S3 for large objects.
Check yourself
Which cache fits a DynamoDB table with the least code change?
DAX, because it uses the DynamoDB API and you only swap the client.
What is the downside of lazy loading?
A cache miss costs an extra database read, and cached data can be stale until its TTL expires.
Where should a 50 MB document be stored?
In Amazon S3, with a reference to its key kept in the database.
Topic 5 of 7 in Development with AWS Services
Test yourself on Development with AWS Services
The full AWS DVA-C03 question bank has 850 questions, with timed practice exams and an explanation for every answer.
This study guide is independent and is not affiliated with, endorsed by, or sponsored by AWS. Vendor names, certification names and exam codes are trademarks of their respective owners and are used for identification only.