Reading25 min read·Module 4

Caching to Reduce Database Load

Key concepts

  • ElastiCache cost vs RDS savings

  • DAX for DynamoDB

  • Cache hit ratio optimization

  • TTL strategies

  • Read-through vs cache-aside

Overview

Implementing caching is one of the most effective strategies for reducing database costs in AWS. By serving frequently accessed data from an in-memory cache instead of hitting the database, you can dramatically reduce read capacity requirements, lower latency, and avoid expensive database scaling. This topic covers ElastiCache, DynamoDB Accelerator (DAX), cache optimization strategies, and how to calculate the cost-benefit of caching implementations.

Caching Economics

Caching creates a fundamental cost trade-off: you pay for cache infrastructure (ElastiCache nodes, DAX clusters) but save significantly on database costs (RDS instance sizing, DynamoDB read capacity). The key insight is that cache costs are typically 10-20% of the database costs they replace. A well-implemented caching layer with 80%+ hit ratio can reduce database load by 80%, often allowing you to downsize database instances by one or two tiers.

Exam Tip

The exam frequently presents scenarios involving high read traffic, database performance issues, or cost optimization requirements. When you see 'reduce database load,' 'improve read performance,' or 'optimize costs for read-heavy workloads,' caching is almost always part of the correct answer. Know when to use ElastiCache Redis vs Memcached and when DAX is the appropriate solution for DynamoDB.

Key Concepts

ElastiCache Cost vs RDS Savings

ElastiCache cost vs RDS savings comparison
Figure 1: ElastiCache Cost vs RDS Savings Analysis

ElastiCache Pricing Model

Purpose: Fully managed in-memory caching service that reduces database load and improves application performance

Pricing Components:

  • Node Hours: Per-hour charge based on node type (cache.t3.micro to cache.r6g.16xlarge)
  • Data Transfer: Data transferred out of ElastiCache (in-region transfer is free)
  • Backup Storage: Automated backups beyond free allocation (Redis only)

Pricing Examples (US-East-1, On-Demand):

  • cache.t3.micro: $0.017/hour (~$12.41/month)
  • cache.r6g.large: $0.136/hour (~$99.28/month)
  • cache.r6g.xlarge: $0.272/hour (~$198.56/month)
  • cache.r6g.2xlarge: $0.544/hour (~$397.12/month)

Reserved Node Savings:

  • 1-year reservation: Up to 31% savings
  • 3-year reservation: Up to 55% savings

Database Cost Reduction Analysis

Cost Comparison Example:

Before Caching (RDS MySQL):

  • db.r6g.2xlarge: $0.96/hour = ~$700/month
  • Multi-AZ: $1.92/hour = ~$1,400/month
  • Read Replicas (3x): Additional ~$2,100/month
  • Total: ~$3,500/month

After Caching (80% cache hit ratio):

  • ElastiCache (cache.r6g.large, 2 nodes): ~$200/month
  • RDS downsized to db.r6g.large: $0.48/hour = ~$350/month
  • Multi-AZ: ~$700/month
  • Read Replicas reduced to 1: ~$350/month
  • Total: ~$1,600/month

Monthly Savings: ~$1,900 (54% reduction)

Key Insight: Cache node cost (~$200) enables RDS savings (~$2,100) - a 10:1 return on cache investment

When Caching Pays Off

High ROI Scenarios:

  • Read-heavy workloads (70%+ reads)
  • Frequently accessed data (hot spots)
  • Data that changes infrequently
  • Complex database queries that can be cached
  • High database instance costs

Low ROI Scenarios:

  • Write-heavy workloads
  • Data that changes every request
  • Highly random access patterns (no hot spots)
  • Very small databases already on minimum instance sizes

Break-Even Analysis:

  • If cache hit ratio < 50%, savings may not justify cache cost
  • If database is already minimal size, no room to downsize
  • Consider operational complexity costs

DAX for DynamoDB

DAX architecture with DynamoDB
Figure 2: DynamoDB Accelerator (DAX) Architecture

DynamoDB Accelerator (DAX) Overview

Purpose: Fully managed, highly available, in-memory cache specifically designed for DynamoDB

Key Characteristics:

  • Microsecond response times (vs milliseconds for DynamoDB)
  • API-compatible with DynamoDB (minimal code changes)
  • Write-through cache (writes go to both cache and DynamoDB)
  • Handles cache invalidation automatically
  • Cluster-based deployment (3+ nodes for production)

DAX vs ElastiCache for DynamoDB:

  • DAX: Purpose-built, API-compatible, automatic cache management
  • ElastiCache: More flexible, requires application-level cache logic
  • DAX: Best for simple caching of DynamoDB reads
  • ElastiCache: Best for complex caching patterns, session storage

DAX Pricing Model

Pricing Components:

  • Node Hours: Per-hour charge based on node type
  • Data Transfer: Free within same AZ, charges for cross-AZ
  • No separate charge for storage (in-memory only)

Pricing Examples (US-East-1, On-Demand):

  • dax.t3.small: $0.04/hour (~$29.20/month)
  • dax.r5.large: $0.269/hour (~$196.37/month)
  • dax.r5.xlarge: $0.538/hour (~$392.74/month)
  • dax.r5.2xlarge: $1.076/hour (~$785.48/month)

Minimum Production Setup (3 nodes):

  • 3x dax.r5.large: ~$589/month

Reserved Capacity Savings:

  • 1-year: Up to 35% savings
  • 3-year: Up to 55% savings

DAX Cost Savings Calculation

Scenario: High-traffic application with 100,000 reads/second

Without DAX (On-Demand DynamoDB):

  • Eventually consistent reads: 50,000 RRUs (100K reads / 2)
  • Cost: 50,000 * $0.00013/RRU/hour = $6.50/hour
  • Monthly: ~$4,745

With DAX (90% cache hit ratio):

  • DAX cluster (3x dax.r5.large): ~$589/month
  • DynamoDB reads reduced to 10,000/second
  • DynamoDB cost: 5,000 RRUs = ~$475/month
  • Total: ~$1,064/month

Monthly Savings: ~$3,681 (78% reduction)

Break-Even Point: DAX pays off when read traffic justifies cluster cost

  • Minimum viable: ~15,000+ reads/second for r5.large cluster

Cache Hit Ratio Optimization

Cache hit ratio optimization strategies
Figure 3: Optimizing Cache Hit Ratio

Understanding Cache Hit Ratio

Definition: The percentage of read requests served from cache vs total read requests

Formula: Cache Hit Ratio = (Cache Hits) / (Cache Hits + Cache Misses) * 100

Impact on Cost Savings: | Hit Ratio | DB Load Reduction | Typical Savings | |-----------|------------------|-----------------| | 50% | 50% | 20-30% cost reduction | | 70% | 70% | 40-50% cost reduction | | 80% | 80% | 50-60% cost reduction | | 90% | 90% | 60-75% cost reduction | | 95% | 95% | 70-80% cost reduction |

Industry Benchmarks:

  • Minimum acceptable: 70%
  • Good: 80-90%
  • Excellent: 90-95%
  • World-class: 95%+

Strategies to Improve Hit Ratio

1. Cache Warming:

  • Pre-populate cache before traffic spikes
  • Load frequently accessed data at startup
  • Use scheduled jobs to refresh popular items

2. Appropriate TTL Settings:

  • Too short: Low hit ratio, frequent DB calls
  • Too long: Stale data, memory pressure
  • Tune based on data change frequency

3. Key Design:

  • Use consistent, predictable key patterns
  • Include version numbers for cache invalidation
  • Avoid overly granular keys (reduces hit probability)

4. Right-Size Cache Memory:

  • Monitor eviction rates
  • If evictions high, increase memory or reduce TTL
  • Use CloudWatch MemoryUsage and Evictions metrics

5. Data Structure Optimization:

  • Cache aggregated/computed results (not raw data)
  • Use appropriate data structures (strings, hashes, sorted sets)
  • Compress large values to fit more in memory

Monitoring Cache Performance

Key CloudWatch Metrics for ElastiCache:

Hit Ratio Metrics:

  • CacheHits: Number of successful cache reads
  • CacheMisses: Number of cache misses
  • CacheHitRate: Percentage of hits (calculated)

Capacity Metrics:

  • BytesUsedForCache: Memory currently used
  • Evictions: Number of items evicted due to memory pressure
  • CurrConnections: Current client connections
  • NewConnections: New connections per second

Health Metrics:

  • CPUUtilization: Node CPU usage
  • NetworkBytesIn/Out: Network throughput
  • ReplicationLag: Replica sync delay (Redis)

Alarm Thresholds:

  • Cache hit ratio < 70%: Investigate access patterns
  • Evictions > 0 sustained: Increase memory
  • CPU > 65%: Consider scaling

TTL Strategies

TTL strategy decision guide
Figure 4: TTL Strategy Decision Framework

TTL (Time to Live) Fundamentals

Purpose: Automatically expire cached data to ensure freshness and manage memory

How TTL Works:

  • Set expiration time when caching data
  • Cache automatically removes expired items
  • Next request triggers cache miss and fresh data fetch

TTL Trade-offs:

  • Short TTL (seconds to minutes): Fresh data, lower hit ratio, more DB load
  • Long TTL (hours to days): Higher hit ratio, potentially stale data
  • No TTL: Maximum hit ratio, manual invalidation required

Cost Impact:

  • Shorter TTL = more database calls = higher database costs
  • Longer TTL = fewer database calls = lower database costs
  • Balance freshness requirements with cost optimization

TTL Strategy by Data Type

Static Configuration Data (Hours to Days):

  • Application settings
  • Feature flags
  • Reference data (countries, categories)
  • TTL: 1-24 hours

User Profile Data (Minutes to Hours):

  • User preferences
  • Account information
  • Permissions/roles
  • TTL: 5-60 minutes

Session Data (Minutes):

  • Shopping carts
  • Authentication tokens
  • Form state
  • TTL: 15-30 minutes

Real-Time Data (Seconds):

  • Stock prices
  • Live scores
  • Inventory counts
  • TTL: 5-60 seconds

Computed Results (Variable):

  • Search results
  • Aggregations
  • Reports
  • TTL: Based on underlying data change frequency

Advanced TTL Patterns

Staggered TTL:

  • Add random jitter to prevent thundering herd
  • Example: Base TTL 60s + random(0-30s)
  • Prevents all caches expiring simultaneously

Sliding TTL:

  • Reset TTL on each access
  • Keeps hot data in cache longer
  • Reduces DB load for popular items

Adaptive TTL:

  • Adjust TTL based on access patterns
  • Popular items: Longer TTL
  • Rarely accessed: Shorter TTL
  • Requires custom implementation

Cache Tags:

  • Group related cache entries
  • Invalidate entire groups at once
  • Example: All user-123 related caches

Read-Through vs Cache-Aside Patterns

Read-through vs cache-aside patterns
Figure 5: Caching Pattern Comparison

Cache-Aside (Lazy Loading)

How It Works:

  1. Application checks cache first
  2. If cache hit: Return cached data
  3. If cache miss: Query database
  4. Store result in cache
  5. Return data to caller

Advantages:

  • Only requested data is cached
  • Cache failures don't break application
  • Simple to implement
  • Works with any database

Disadvantages:

  • First request always hits database
  • Application manages cache logic
  • Potential for stale data
  • Cache misses add latency (cache check + DB call)

Best For:

  • General-purpose caching
  • Applications with unpredictable access patterns
  • When database can handle cache miss spikes

Read-Through Cache

How It Works:

  1. Application always reads from cache
  2. Cache automatically fetches from database on miss
  3. Cache manages data loading logic
  4. Application code simplified

Advantages:

  • Simpler application code
  • Consistent cache population logic
  • Cache handles database interaction
  • Better abstraction

Disadvantages:

  • Cache becomes critical path
  • More complex cache infrastructure
  • Limited flexibility in fetch logic
  • May cache unnecessary data

Best For:

  • Standardized data access patterns
  • When cache infrastructure can handle load
  • Reducing application complexity

AWS Implementation: DAX is a read-through cache for DynamoDB

Write-Through Cache

How It Works:

  1. Application writes to cache
  2. Cache synchronously writes to database
  3. Both updated before confirming write
  4. Read always from cache

Advantages:

  • Cache always has latest data
  • No stale data issues
  • Simplified read path
  • Consistent data

Disadvantages:

  • Write latency increased
  • Cache failures can block writes
  • All data cached (even if never read)
  • Higher cache memory usage

Best For:

  • Read-heavy workloads
  • Data that must always be fresh
  • When write latency is acceptable

AWS Implementation: DAX uses write-through for DynamoDB

Write-Behind (Write-Back) Cache

How It Works:

  1. Application writes to cache only
  2. Cache acknowledges immediately
  3. Cache asynchronously writes to database
  4. Batches writes for efficiency

Advantages:

  • Fastest write performance
  • Reduced database write load
  • Batching improves efficiency
  • Lower database costs

Disadvantages:

  • Risk of data loss if cache fails
  • Eventual consistency
  • Complex failure handling
  • Not suitable for critical data

Best For:

  • Write-heavy workloads
  • When some data loss is acceptable
  • Analytics and logging
  • Non-critical updates

Caching Pattern Selection Guide

PatternData FreshnessPerformanceComplexityBest Use Case
Cache-AsideDepends on TTLGood (miss penalty)LowGeneral-purpose, flexible requirements
Read-ThroughDepends on TTLGood (miss penalty)MediumStandardized read patterns
Write-ThroughAlways freshGood reads, slower writesMediumRead-heavy, fresh data required
Write-BehindEventually consistentFastest writesHighWrite-heavy, loss acceptable

Best Practices

  1. Start with Cache-Aside for Flexibility: Begin with the cache-aside pattern as it is simplest to implement and provides the most control over caching behavior

  2. Target 80%+ Cache Hit Ratio: Design your caching strategy to achieve at least 80% cache hit ratio before investing in caching infrastructure

  3. Use DAX for DynamoDB-Only Workloads: When caching only DynamoDB data, DAX provides the simplest implementation with automatic cache management

  4. Set Appropriate TTLs by Data Type: Match TTL to data change frequency - static data can have long TTLs, frequently changing data needs shorter TTLs

  5. Monitor and Alert on Cache Metrics: Set up CloudWatch alarms for cache hit ratio, evictions, and memory usage to detect issues early

  6. Implement Cache Warming for Predictable Traffic: Pre-populate caches before known traffic spikes to avoid cold cache penalties

  7. Use Multi-AZ for Production Caches: Deploy ElastiCache clusters across multiple AZs for high availability, especially for session stores

  8. Right-Size Cache Nodes: Monitor memory usage and eviction rates to find the optimal node size - too small causes evictions, too large wastes money

Common Exam Scenarios

Caching Exam Scenario Decision Guide

ScenarioRecommended SolutionKey Reasoning
DynamoDB table with very high read traffic causing throttlingImplement DAX clusterDAX is purpose-built for DynamoDB, provides microsecond latency, reduces RCU consumption
RDS database experiencing high CPU due to repeated read queriesAdd ElastiCache Redis clusterCache frequently accessed queries, reduce database load, improve response time
Need to store user session data with sub-millisecond latencyElastiCache Redis with Multi-AZIn-memory storage for sessions, Redis persistence for durability, Multi-AZ for HA
E-commerce product catalog with millions of reads per dayElastiCache with cache-aside patternCache product data, invalidate on updates, handle high read volume cost-effectively
Real-time leaderboard requiring sorted dataElastiCache Redis sorted setsRedis sorted sets provide efficient leaderboard operations with automatic ranking
Reduce costs for read-heavy DynamoDB table with predictable access patternsDAX with reserved capacityDAX reduces RCU costs, reserved capacity provides additional savings
Application experiencing cold start latency after deploymentsImplement cache warming during deploymentPre-populate cache to avoid miss penalties, maintain consistent performance
Need to cache complex join queries from AuroraElastiCache Redis with query result cachingCache computed results of expensive queries, significant database offload

Common Pitfalls

Caching Without Measuring Hit Ratio

Implementing caching without monitoring cache hit ratio can lead to wasted infrastructure costs. If your cache hit ratio is below 70%, you may be paying for cache infrastructure without meaningful database savings. Always implement CloudWatch monitoring for cache hits and misses before assuming cost benefits.

Using ElastiCache When DAX is Better

For DynamoDB-only caching needs, using ElastiCache instead of DAX adds unnecessary complexity. DAX is API-compatible with DynamoDB, handles cache invalidation automatically, and requires minimal code changes. Only use ElastiCache for DynamoDB when you need features DAX doesn't provide (like sorted sets or pub/sub).

Setting TTL Too Short

Overly aggressive TTLs (seconds) can result in cache hit ratios below 50%, negating the benefits of caching. If your data doesn't change frequently, use longer TTLs. A 5-minute TTL often provides 10x better hit ratio than a 30-second TTL with minimal freshness impact for most use cases.

Not Planning for Cache Failures

Applications must handle cache failures gracefully. If your application cannot function when the cache is unavailable, you have created a single point of failure. Implement circuit breakers and fallback to database during cache outages. Never let cache failures cascade to application failures.

Caching User-Specific Data Without Proper Keys

Caching personalized data without including user identifiers in cache keys can leak data between users - a serious security vulnerability. Always include user ID, tenant ID, or session ID in cache keys for user-specific data. Example: user:12345:preferences not just preferences.

Quick Reference

Caching Service Comparison

FeatureElastiCache RedisElastiCache MemcachedDAX
PurposeGeneral cachingSimple cachingDynamoDB caching
Data StructuresRich (strings, hashes, lists, sets, sorted sets)Key-value onlyKey-value only
PersistenceYes (RDB, AOF)NoNo
ReplicationYesNoYes
Multi-AZYesNoYes
ClusteringYesYesYes
Max Nodes500 (cluster mode)4011
APIRedis commandsMemcached protocolDynamoDB API
Use CaseSessions, leaderboards, complex cachingSimple cachingDynamoDB read acceleration

ElastiCache Pricing Quick Reference (US-East-1, On-Demand)

Node TypeMemoryPrice/HourPrice/Month
cache.t3.micro0.5 GB$0.017~$12
cache.t3.small1.37 GB$0.034~$25
cache.t3.medium3.09 GB$0.068~$50
cache.r6g.large13.07 GB$0.136~$99
cache.r6g.xlarge26.32 GB$0.272~$199
cache.r6g.2xlarge52.82 GB$0.544~$397

DAX Pricing Quick Reference (US-East-1, On-Demand)

Node TypeMemoryPrice/HourPrice/Month
dax.t3.small2 GB$0.04~$29
dax.t3.medium4 GB$0.08~$58
dax.r5.large16 GB$0.269~$196
dax.r5.xlarge32 GB$0.538~$393
dax.r5.2xlarge64 GB$1.076~$785

Cache Hit Ratio Impact Calculator

Starting DB CostCache CostHit RatioDB ReductionNet Savings
$1,000/month$100/month80%$800/month$700/month (70%)
$1,000/month$100/month90%$900/month$800/month (80%)
$5,000/month$300/month80%$4,000/month$3,700/month (74%)
$5,000/month$300/month90%$4,500/month$4,200/month (84%)

Essential CLI Commands

SHAWS CLI - Create ElastiCache Redis Cluster
# Create a Redis replication group with Multi-AZ
aws elasticache create-replication-group \
  --replication-group-id my-redis-cluster \
  --replication-group-description "Production Redis cache" \
  --engine redis \
  --cache-node-type cache.r6g.large \
  --num-cache-clusters 3 \
  --automatic-failover-enabled \
  --multi-az-enabled \
  --cache-subnet-group-name my-subnet-group \
  --security-group-ids sg-12345678

# List ElastiCache clusters
aws elasticache describe-cache-clusters \
  --query 'CacheClusters[*].[CacheClusterId,CacheNodeType,Engine,CacheClusterStatus]'
SHAWS CLI - Create DAX Cluster
# Create DAX cluster
aws dax create-cluster \
  --cluster-name my-dax-cluster \
  --node-type dax.r5.large \
  --replication-factor 3 \
  --iam-role-arn arn:aws:iam::123456789012:role/DAXRole \
  --subnet-group-name my-dax-subnet-group \
  --security-group-ids sg-12345678

# Describe DAX clusters
aws dax describe-clusters \
  --query 'Clusters[*].[ClusterName,NodeType,TotalNodes,Status]'
SHAWS CLI - Monitor Cache Performance
# Get ElastiCache hit/miss metrics
aws cloudwatch get-metric-statistics \
  --namespace AWS/ElastiCache \
  --metric-name CacheHits \
  --dimensions Name=CacheClusterId,Value=my-cluster \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 300 \
  --statistics Sum

# Get cache miss count
aws cloudwatch get-metric-statistics \
  --namespace AWS/ElastiCache \
  --metric-name CacheMisses \
  --dimensions Name=CacheClusterId,Value=my-cluster \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 300 \
  --statistics Sum

# Get evictions (indicates memory pressure)
aws cloudwatch get-metric-statistics \
  --namespace AWS/ElastiCache \
  --metric-name Evictions \
  --dimensions Name=CacheClusterId,Value=my-cluster \
  --start-time $(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 3600 \
  --statistics Sum
SHAWS CLI - ElastiCache Reserved Node Purchase
# List available reserved cache node offerings
aws elasticache describe-reserved-cache-nodes-offerings \
  --cache-node-type cache.r6g.large \
  --duration 31536000 \
  --product-description "redis" \
  --query 'ReservedCacheNodesOfferings[*].[OfferingType,Duration,FixedPrice,RecurringCharges]'

# Purchase reserved cache node
aws elasticache purchase-reserved-cache-nodes-offering \
  --reserved-cache-nodes-offering-id <offering-id> \
  --cache-node-count 3

# List current reserved nodes
aws elasticache describe-reserved-cache-nodes \
  --query 'ReservedCacheNodes[*].[ReservedCacheNodeId,CacheNodeType,Duration,State]'

TTL Strategy Quick Reference

Data TypeRecommended TTLRationale
Static configuration1-24 hoursRarely changes, high hit ratio
User profiles5-60 minutesChanges occasionally
Session data15-30 minutesSecurity, cleanup
Product catalog5-30 minutesBalance freshness and performance
Search results1-5 minutesAcceptable staleness
Real-time prices5-60 secondsAccuracy important
Computed aggregationsBased on source dataInvalidate on change

Test Your Knowledge

Q

A company has a DynamoDB table serving 50,000 read requests per second. They want to reduce costs while maintaining sub-millisecond read latency. What is the MOST cost-effective solution?

AAdd a 3-node DAX cluster to cache DynamoDB reads
BIncrease DynamoDB provisioned read capacity units
CSwitch DynamoDB to on-demand capacity mode
DAdd ElastiCache Redis cluster with custom caching logic
Q

An application uses ElastiCache Redis for caching database queries. CloudWatch shows 45% cache hit ratio and high eviction rates. What should the solutions architect do FIRST to optimize cache performance?

AIncrease the cache node size to reduce evictions
BReduce TTL values to free up memory faster
CImplement cache warming to pre-populate the cache
DReview access patterns and cache key design
Q

A solutions architect is designing a caching strategy for an e-commerce application. Product catalog data changes daily, but product prices change every few hours during sales. Which TTL strategy is MOST appropriate?

ASet 24-hour TTL for all product data and invalidate on changes
BSet 1-hour TTL for all product data
CSet 24-hour TTL for catalog data and 15-minute TTL for prices with cache tags
DSet 5-minute TTL for all product data to ensure freshness
Q

A company runs a session store on ElastiCache Redis. They want to ensure zero session loss during infrastructure failures. Which configuration provides the HIGHEST durability?

ASingle Redis node with RDB persistence
BRedis cluster mode disabled with Multi-AZ and AOF persistence
CRedis cluster mode enabled across 3 AZs
DMemcached cluster with 3 nodes across AZs

Further Reading

Related services

ElastiCacheDAX