← Back to DevBytes

Monitoring ElastiCache: Metrics, Alarms, and Dashboards

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

Memcached (Cluster and Node) Metrics

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

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.

🚀 Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started — $23.99/mo
← Back to all articles