Monitoring Amazon ElastiCache: Metrics, Alarms, and Dashboards
Amazon ElastiCache, whether running Redis or Memcached, is a critical in-memory data store that accelerates application performance. Monitoring its health and behaviour is not optional — it’s essential to maintain low latency, prevent cache eviction storms, avoid memory exhaustion, and catch replication issues before they cascade into application failures. This tutorial walks you through the native CloudWatch metrics, how to set meaningful alarms, and how to build rich operational dashboards, all backed by practical code examples you can run today.
What you’ll monitor
ElastiCache exposes two tiers of metrics in CloudWatch: cluster-level metrics (aggregated across all nodes in the cluster) and node-level metrics (each individual cache node). Both tiers are essential. Cluster metrics give you a bird’s-eye view of cache efficiency, while node metrics help you spot uneven load distribution, single-node memory pressure, or CPU spikes. All metrics are published to the AWS/ElastiCache namespace, with dimensions like CacheClusterId for single shards/clusters or CacheClusterId, ShardId for specific shards in a Redis replication group.
Why monitoring matters
A poorly monitored ElastiCache instance can silently degrade. High CPU or memory usage may cause evictions, increasing database load and slowing your entire application. A drop in cache hit ratio often goes unnoticed until users complain about sluggish performance. Replication lag can lead to stale reads from read replicas. Without alarms, you react after the damage is done. With a dashboard, you spot trends early and can proactively scale or adjust instance types.
Key Metrics to Watch
Redis (Cluster and Node) Metrics
- CPUUtilization – Percentage of CPU consumed. High values indicate the node is under-provisioned or handling too many requests.
- DatabaseMemoryUsagePercentage – Percentage of the total memory used for Redis data. Approaching 100% triggers evictions or even write failures if no eviction policy is set.
- CacheHitRate – Ratio of successful key lookups to total lookups. A healthy Redis cluster often sits above 0.9 (90%).
- CacheMissRate – Complement of hit rate; a spike often means keys are expiring or being evicted too aggressively.
- ReplicationLag – Seconds that replica nodes lag behind the primary. Persistent lag > 1 second can cause stale reads and should fire an alarm.
- SwapUsage – Amount of swap used. Any swap usage on a Redis node is a red flag, indicating severe memory pressure.
- Evictions – Number of keys evicted due to memory constraints. A growing eviction count calls for more memory or a review of eviction policy.
- CurrConnections – Number of active client connections. Sudden spikes may indicate a client storm or connection leaks.
Memcached (Cluster and Node) Metrics
- CPUUtilization – Same as Redis; watch for sustained high utilisation.
- FreeableMemory – Bytes of free memory available on the node. Drops to a low value mean you’re close to exhausting the allocated memory.
- SwapUsage – Swap on Memcached is equally dangerous; alarm if it’s non-zero.
- CacheHitRate / CacheMissRate – Memcached reports these at the cluster level; use them to gauge cache effectiveness.
- Evictions – Memcached evicts based on its own LRU algorithm; monitor to know when you need to scale horizontally (add nodes) or increase node memory.
- CurrConnections – Important for tracking connection limits.
Understanding Cache Hit Ratio
Cache hit ratio is not a raw metric but is available as CacheHitRate and CacheMissRate. They are calculated as CacheHits / (CacheHits + CacheMisses). You can also use CloudWatch Metric Math to build a composite expression if you prefer working with raw CacheHits and CacheMisses. A drop below your baseline (e.g., 0.8) often signals a change in workload patterns, insufficient memory, or an expiring key avalanche.
Setting Up CloudWatch Alarms
Alarms turn passive monitoring into active protection. You define a threshold, a period, and an action (typically an SNS topic that pages your team). Below are practical AWS CLI examples you can adapt with your own cluster identifiers and SNS topic ARNs.
Alarm for High CPU on a Redis Node
aws cloudwatch put-metric-alarm \
--alarm-name "ElastiCache-HighCPU" \
--alarm-description "Alarm when CPU exceeds 80% for 2 periods of 5 minutes" \
--namespace "AWS/ElastiCache" \
--metric-name "CPUUtilization" \
--dimensions Name=CacheClusterId,Value=my-redis-cluster \
--statistic Average \
--period 300 \
--evaluation-periods 2 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--alarm-actions arn:aws:sns:us-east-1:123456789012:elastisense-alerts
This alarm triggers when the average CPU over two consecutive 5-minute windows exceeds 80%. Adjust the threshold and period based on your workload’s tolerance.
Alarm for Low Cache Hit Rate
aws cloudwatch put-metric-alarm \
--alarm-name "ElastiCache-LowHitRate" \
--alarm-description "Alarm when CacheHitRate drops below 0.8 for 2 periods" \
--namespace "AWS/ElastiCache" \
--metric-name "CacheHitRate" \
--dimensions Name=CacheClusterId,Value=my-redis-cluster \
--statistic Average \
--period 300 \
--evaluation-periods 2 \
--threshold 0.8 \
--comparison-operator LessThanThreshold \
--alarm-actions arn:aws:sns:us-east-1:123456789012:elastisense-alerts
Alarm for High Replication Lag (Redis only)
aws cloudwatch put-metric-alarm \
--alarm-name "ElastiCache-ReplicationLag" \
--alarm-description "Alarm when ReplicationLag exceeds 10 seconds" \
--namespace "AWS/ElastiCache" \
--metric-name "ReplicationLag" \
--dimensions Name=CacheClusterId,Value=my-redis-cluster \
--statistic Maximum \
--period 300 \
--evaluation-periods 1 \
--threshold 10 \
--comparison-operator GreaterThanThreshold \
--alarm-actions arn:aws:sns:us-east-1:123456789012:elastisense-alerts
Composite Alarm Using Metric Math
Sometimes a single metric isn’t enough — you want to alert only when CPU is high and cache hit ratio is low. CloudWatch supports metric math expressions to combine metrics. Here’s how to create a composite alarm with the CLI:
aws cloudwatch put-metric-alarm \
--alarm-name "ElastiCache-HighCPUAndLowHitRate" \
--alarm-description "CPU > 80% AND CacheHitRate < 0.8" \
--metrics '[
{
"Id": "cpu",
"MetricStat": {
"Metric": {
"Namespace": "AWS/ElastiCache",
"MetricName": "CPUUtilization",
"Dimensions": [{"Name":"CacheClusterId","Value":"my-redis-cluster"}]
},
"Stat": "Average",
"Period": 300
},
"ReturnData": false
},
{
"Id": "hitrate",
"MetricStat": {
"Metric": {
"Namespace": "AWS/ElastiCache",
"MetricName": "CacheHitRate",
"Dimensions": [{"Name":"CacheClusterId","Value":"my-redis-cluster"}]
},
"Stat": "Average",
"Period": 300
},
"ReturnData": false
},
{
"Id": "combined",
"Expression": "(cpu > 80) AND (hitrate < 0.8)",
"Label": "HighCPUAndLowHitRate",
"ReturnData": true
}
]' \
--evaluation-periods 2 \
--threshold 1 \
--comparison-operator GreaterThanThreshold \
--alarm-actions arn:aws:sns:us-east-1:123456789012:elastisense-alerts
The expression returns 1 when both conditions are true, and the alarm triggers when that value exceeds 0 (threshold of 1) for two consecutive periods.
Building CloudWatch Dashboards
Dashboards give you a single pane of glass for your ElastiCache environment. You can combine CPU, memory, hit ratio, replication lag, and connection counts into widgets, arranged in a layout that suits your operations team.
Dashboard JSON Example
Below is a complete dashboard JSON body that creates a dashboard named ElastiCache-Monitoring with four widgets: a time-series CPU graph, a hit ratio graph, a memory usage graph, and a single-value widget showing replication lag.
{
"widgets": [
{
"type": "metric",
"x": 0,
"y": 0,
"width": 12,
"height": 6,
"properties": {
"view": "timeSeries",
"stacked": false,
"metrics": [
[ "AWS/ElastiCache", "CPUUtilization", "CacheClusterId", "my-redis-cluster" ],
[ "AWS/ElastiCache", "CPUUtilization", "CacheClusterId", "my-redis-cluster-001", { "stat": "Average" } ]
],
"region": "us-east-1",
"title": "CPU Utilization",
"period": 300,
"stat": "Average"
}
},
{
"type": "metric",
"x": 12,
"y": 0,
"width": 12,
"height": 6,
"properties": {
"view": "timeSeries",
"stacked": false,
"metrics": [
[ "AWS/ElastiCache", "CacheHitRate", "CacheClusterId", "my-redis-cluster" ],
[ "AWS/ElastiCache", "CacheMissRate", "CacheClusterId", "my-redis-cluster" ]
],
"region": "us-east-1",
"title": "Cache Hit & Miss Rate",
"period": 300,
"stat": "Average"
}
},
{
"type": "metric",
"x": 0,
"y": 6,
"width": 12,
"height": 6,
"properties": {
"view": "timeSeries",
"stacked": false,
"metrics": [
[ "AWS/ElastiCache", "DatabaseMemoryUsagePercentage", "CacheClusterId", "my-redis-cluster" ],
[ "AWS/ElastiCache", "SwapUsage", "CacheClusterId", "my-redis-cluster" ]
],
"region": "us-east-1",
"title": "Memory and Swap",
"period": 300,
"stat": "Average"
}
},
{
"type": "metric",
"x": 12,
"y": 6,
"width": 12,
"height": 6,
"properties": {
"view": "singleValue",
"metrics": [
[ "AWS/ElastiCache", "ReplicationLag", "CacheClusterId", "my-redis-cluster", { "stat": "Maximum" } ]
],
"region": "us-east-1",
"title": "Max Replication Lag (seconds)",
"period": 300,
"stat": "Maximum"
}
}
]
}
Deploying the Dashboard via CLI
Save the JSON to a file, say dashboard.json, and run:
aws cloudwatch put-dashboard \
--dashboard-name "ElastiCache-Monitoring" \
--dashboard-body file://dashboard.json
You can also inline the JSON string directly, but using a file is cleaner for complex dashboards. The dashboard appears immediately in the CloudWatch console and can be shared with your team.
Automating with Infrastructure as Code
Manually creating alarms and dashboards doesn’t scale. Embed them in your CloudFormation templates or CDK stacks so they’re consistently deployed alongside every ElastiCache cluster. Below is a CloudFormation snippet that creates a CPU alarm and a dashboard in one stack.
CloudFormation Example
Resources:
ElastiCacheHighCPUAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: !Sub "${ElastiCacheCluster}-HighCPU"
AlarmDescription: "CPU > 80% for 2 periods"
Namespace: "AWS/ElastiCache"
MetricName: "CPUUtilization"
Dimensions:
- Name: "CacheClusterId"
Value: !Ref ElastiCacheCluster
Statistic: "Average"
Period: 300
EvaluationPeriods: 2
Threshold: 80
ComparisonOperator: "GreaterThanThreshold"
AlarmActions:
- !Ref AlertSnsTopic
ElastiCacheDashboard:
Type: AWS::CloudWatch::Dashboard
Properties:
DashboardName: "ElastiCache-Monitoring-Stack"
DashboardBody: !Sub |
{
"widgets": [
{
"type": "metric",
"x": 0,
"y": 0,
"width": 24,
"height": 6,
"properties": {
"view": "timeSeries",
"metrics": [
[ "AWS/ElastiCache", "CPUUtilization", "CacheClusterId", "${ElastiCacheCluster}" ]
],
"region": "${AWS::Region}",
"title": "CPU",
"period": 300,
"stat": "Average"
}
},
{
"type": "metric",
"x": 0,
"y": 6,
"width": 24,
"height": 6,
"properties": {
"view": "timeSeries",
"metrics": [
[ "AWS/ElastiCache", "CacheHitRate", "CacheClusterId", "${ElastiCacheCluster}" ],
[ "AWS/ElastiCache", "CacheMissRate", "CacheClusterId", "${ElastiCacheCluster}" ]
],
"region": "${AWS::Region}",
"title": "Cache Ratio",
"period": 300,
"stat": "Average"
}
}
]
}
Adjust the widget layout and metrics to suit your environment. For Terraform, use aws_cloudwatch_metric_alarm and aws_cloudwatch_dashboard resources following the same patterns.
Best Practices
- Establish baselines first – Run your workload for a few days, observe normal ranges for CPU, memory, hit ratio, and replication lag. Set thresholds based on real behaviour, not arbitrary numbers.
- Monitor both hit rate and evictions – A high hit rate can still be accompanied by a rising eviction count if memory is tight. Evictions are the canary for “I need more memory or a better eviction policy.”
- Use composite alarms for nuanced conditions – Alert only when CPU is high and hit rate is low; this reduces noise from temporary spikes that don’t affect cache effectiveness.
- Alert on swap, not just freeable memory – Any non-zero swap on ElastiCache (Redis or Memcached) indicates memory pressure that can cause latency spikes. Set a threshold of 0 bytes.
- Set replication lag alarms with a short period – Use 1-minute periods and a max statistic to catch lag quickly; 10 seconds of lag is often unacceptable for read-replica freshness.
- Include dashboard in your CI/CD pipeline – Automate dashboard creation so every environment (dev, staging, prod) gets a consistent monitoring view.
- Leverage CloudWatch anomaly detection – For metrics with seasonal patterns, consider enabling anomaly detection models instead of static thresholds to reduce false alarms.
- Tag alarms with ownership – Use tags or naming conventions to map alarms to teams, so the right people receive notifications.
Conclusion
Monitoring ElastiCache with CloudWatch metrics, alarms, and dashboards is a foundational practice for any team relying on in-memory caching. The built-in metrics cover everything from raw resource usage (CPU, memory) to application-level indicators (cache hit ratio, replication lag). By turning those metrics into actionable alarms, you shift from reactive firefighting to proactive reliability engineering. By building dashboards, you create a shared operational picture that helps everyone understand cache health at a glance. Start with the CLI examples above, then embed monitoring into your Infrastructure as Code, and continuously tune thresholds as your workload evolves. A well-monitored ElastiCache cluster not only performs better but also costs less in the long run because you scale based on evidence, not guesswork.