Chapter 61 · Amazon Elasticache
Subchapter 61.36
references/monitoring/troubleshooting.mdMarkdown18 KBView on GitHub
Symptom-based runbooks for diagnosing and resolving common ElastiCache operational issues.
| Symptom | First Metric to Check | First Action | Deployment |
|---|---|---|---|
| Slow responses | EngineCPUUtilization | Check slow log for expensive commands | Both |
| Low hit rate | CacheHitRate, Evictions | Verify TTLs and eviction policy | Both |
| Connection errors | CurrConnections | Check security groups and connection pooling | Both |
| High CPU | EngineCPUUtilization per node | Look for hot keys or expensive commands | Node-based |
| OOM / write failures | DatabaseMemoryUsagePercentage | Check eviction policy and key TTLs | Node-based |
| Stale reads | ReplicationLag | Check write volume and replica capacity | Node-based |
| Throttled (serverless) | ThrottledCmds, ElastiCacheProcessingUnits | Increase ECPU limit | Serverless |
| Connection drops | describe-events | Check for failover events, verify retry logic | Both |
All investigation steps below reference metrics by name. Use this template, substituting the metric name and dimensions.
aws cloudwatch get-metric-statistics \
--namespace AWS/ElastiCache --metric-name <metric-name> \
--dimensions Name=<dimension-name>,Value=<dimension-value> \
--start-time <start> --end-time <now> --period <seconds> --statistics <stat> \
--region <region>Common dimensions: ReplicationGroupId (cluster-wide), CacheClusterId (per node), ServerlessCacheName (serverless).
| Metric | Deployment | Unit | Common Mistake |
|---|---|---|---|
| ReplicationLag | Node-based | Seconds | Not milliseconds. Threshold of 1 = 1 second. |
| SuccessfulReadRequestLatency | Both | Microseconds | Not milliseconds. 5000 = 5ms. |
| SuccessfulWriteRequestLatency | Both | Microseconds | Not milliseconds. 5000 = 5ms. |
| BytesUsedForCache | Both | Bytes | Not GB. 1 GB = 1,073,741,824 bytes. |
| ElastiCacheProcessingUnits | Serverless | Count (ECPUs) | Sum over period, not rate. |
| ThrottledCmds | Serverless | Count | Sum over period. |
| DatabaseMemoryUsagePercentage | Node-based | Percent | Not a ratio. 80 = 80%. |
| DatabaseCapacityUsagePercentage | Node-based | Percent | Available on all node-based clusters. On data-tiering instances (r6gd), the formula includes SSD storage; on all other instances, it is calculated as used_memory/maxmemory. |
| EngineCPUUtilization | Node-based | Percent | Single-threaded engine; can hit 100% on one core while host CPU is low. |
| CacheHitRate | Both | Percent | Empty until cache serves real traffic. |
| Slow log duration | Both | Microseconds | Not milliseconds. 10000 = 10ms. |
New caches take 5-10 minutes to emit their first CloudWatch datapoints. Serverless caches with zero traffic emit no metrics at all (this is normal, not broken). After confirming the cache exists with describe-serverless-caches or describe-replication-groups, wait for traffic before investigating further.
Applies to: Both serverless and node-based. Severity: P1 (fix now)
| Aspect | Detail |
|---|---|
| Symptoms | SuccessfulReadRequestLatency or SuccessfulWriteRequestLatency elevated |
| Key metrics | EngineCPUUtilization, SuccessfulReadRequestLatency, SuccessfulWriteRequestLatency, CurrConnections |
KEYS *, SMEMBERS on large sets, HGETALL on large hashes, SORT on large listsCheck: EngineCPUUtilization (per node, Maximum), CurrConnections (Maximum). For slow log:
aws logs filter-log-events --log-group-name <your-slow-log-group> \
--region <region>Stop condition: If EngineCPUUtilization is below 60% and CurrConnections is stable, this is not a capacity or connection problem. Check slow log for expensive commands next.
KEYS with SCAN, use SSCAN/HSCAN/ZSCAN for large data structureshot-key-detection.md. For intermittent spikes with slow-log correlation, see slow-log-cross-signal-diagnosis.md.Applies to: Both serverless and node-based. Severity: P2 (fix next business day)
| Aspect | Detail |
|---|---|
| Symptoms | CacheHitRate below 80%, backing store load not decreasing |
| Key metrics | CacheHits, CacheMisses, CacheHitRate, Evictions, DatabaseMemoryUsagePercentage |
Check: Evictions (Sum), DatabaseMemoryUsagePercentage (Maximum), CacheHitRate (Average). All at ReplicationGroupId level.
Stop condition: If Evictions is zero and DatabaseMemoryUsagePercentage is below 70%, eviction is not the cause. Focus on key naming and TTL mismatch.
allkeys-lru for general caching. Use volatile-lru only if some keys must never be evicted. Note: Serverless caches use volatile-lru and this is not configurable; ensure all keys have TTLs set to enable eviction on serverless.Applies to: Both serverless and node-based. Severity: P1 (fix now)
| Aspect | Detail |
|---|---|
| Symptoms | CurrConnections spikes, NewConnections elevated, connection errors in app logs |
| Key metrics | CurrConnections, NewConnections, EngineCPUUtilization |
Check: CurrConnections (Maximum, period 60s), NewConnections (Sum, period 60s). Compare per-node to find imbalance.
max_connections in client library)finally blocksApplies to: Node-based only. For serverless, see Throttling. Severity: P1 (fix now)
| Aspect | Detail |
|---|---|
| Symptoms | EngineCPUUtilization above 90%, increased latency |
| Key metrics | EngineCPUUtilization, CPUUtilization, CurrConnections |
EngineCPUUtilization measures only the main Redis/Valkey engine thread and is the recommended metric for monitoring engine capacity. CPUUtilization reflects aggregate CPU usage across all cores, including dedicated I/O threads from Enhanced I/O features, and is not a reliable indicator of engine capacity for nodes with 4+ vCPUs. For nodes with 2 or fewer vCPUs, use CPUUtilization with a threshold of 90 divided by the number of cores (e.g., 45% for 2-core nodes). For nodes with 4+ vCPUs, use EngineCPUUtilization with a 90% threshold.
KEYS, SORT, SUNIONSTORE on large datasets, complex Lua scriptsCheck: EngineCPUUtilization (per node via CacheClusterId, Maximum, period 60s). Compare across nodes to find hot shards. For slow log:
aws logs filter-log-events --log-group-name <your-slow-log-group> \
--region <region>Also check command-family metrics (StringBasedCmds, HashBasedCmds, etc.) on the hot node to identify the data type driving load before scanning slow logs.
hotkey:1, hotkey:2) and load-balance readsKEYS with SCAN, use SSCAN/HSCAN/ZSCAN, limit Lua complexitymodify-replication-group-shard-configuration), rebalance slotsApplies to: Node-based primarily. Serverless auto-scales storage but can hit configured limits. Severity: P1 (fix now)
| Aspect | Detail |
|---|---|
| Symptoms | DatabaseMemoryUsagePercentage above 80%, Evictions increasing, OOM errors |
| Key metrics | DatabaseMemoryUsagePercentage, BytesUsedForCache, Evictions, CurrItems. For data-tiering instances (r6gd), also check DatabaseCapacityUsagePercentage which covers both memory and SSD tiers. |
maxmemory-policy set to noeviction, rejects writes when fullMemoryFragmentationRatioCheck: DatabaseMemoryUsagePercentage (Maximum, period 3600s over 7d), Evictions (Sum, period 3600s over 7d). To check eviction policy:
aws elasticache describe-cache-parameters \
--cache-parameter-group-name <parameter-group> \
--region <region> \
--query "Parameters[?ParameterName=='maxmemory-policy']"Stop condition: If Evictions is zero and memory is rising slowly, this may be normal growth. Only act if approaching 80% or evictions are sustained.
maxmemory-policy to allkeys-lrubig-key-hunter.md.activedefrag to yes in the parameter group (CONFIG SET is restricted on ElastiCache).OBJECT IDLETIME to find stale keys.reserved-memory-percent to 25 (for Valkey and Redis OSS 2.8.22+) or 50 (for older Redis OSS versions) via a custom parameter group. The default is 25% for all parameter group families (available since March 2017). For accounts created before March 16, 2017, older parameter families may default to 0. A value of 0 allows the engine to consume all of maxmemory with data, leaving insufficient memory for background write processes (BGSAVE, replication sync), which can cause snapshot and sync failures.Applies to: Node-based only. Serverless handles replication internally. Severity: P2 (fix next business day, P1 if > 5s)
| Aspect | Detail |
|---|---|
| Symptoms | ReplicationLag above 1s, stale reads from replicas, failover risk |
| Key metrics | ReplicationLag, ReplicationBytes, NetworkBytesOut (primary), SaveInProgress |
BGSAVE/snapshot operations competing for I/OCheck: ReplicationLag (per replica via CacheClusterId, Maximum, period 60s), SaveInProgress (per primary, Maximum, period 60s).
Stop condition: If SaveInProgress is 1 and lag correlates with snapshot timing, this is snapshot-induced. Schedule snapshots during off-peak rather than scaling.
Applies to: Serverless only. Severity: P1 (fix now)
| Aspect | Detail |
|---|---|
| Symptoms | ThrottledCmds increasing, throttle errors in clients, ElastiCacheProcessingUnits near max |
| Key metrics | ThrottledCmds, ElastiCacheProcessingUnits |
CacheUsageLimits.ECPUPerSecond.Maximum too low for current workloadSORT, ZRANGEBYSCORE returning thousands)Check: ElastiCacheProcessingUnits (Sum, period 60s), ThrottledCmds (Sum, period 60s). Use ServerlessCacheName dimension.
Increase ECPU limit:
aws elasticache modify-serverless-cache \
--serverless-cache-name <name> \
--cache-usage-limits '{"ECPUPerSecond": {"Maximum": <higher-value>}}' \
--region <region>Optimize commands: replace expensive operations with efficient alternatives, use pipelining
Cost concern: consider node-based for steady-state high-throughput with reserved pricing
Add client-side retry: exponential backoff for throttled commands
Applies to: Node-based primarily. Serverless handles failover transparently. Severity: P1 (fix now)
| Aspect | Detail |
|---|---|
| Symptoms | Brief connection interruption, DNS endpoint change |
| Key metrics | ReplicationLag (pre-failover), events from describe-events |
test-failoverCheck recent events:
aws elasticache describe-events \
--source-type replication-group \
--source-identifier <replication-group-id> \
--duration 1440 \
--region <region>Also check ReplicationLag (Maximum) before the event; high lag means potential data loss.
ReplicationLag low. High lag before failover means unreplicated writes are lost.Applies to: Both serverless and node-based. Severity: P1 (fix now)
| Aspect | Detail |
|---|---|
| Symptoms | Connection timeout, connection refused, TLS handshake failure |
| Key metrics | CurrConnections (if any succeed), describe-events for failover |
CurrConnections against node’s maxclients (default 65,000 for most instance types; exceptions: t2.micro/small/medium and t3.micro = 20,000; t3.small/medium = 46,000; t4g.micro = 20,000)Check describe-events for recent failover. Verify security group allows inbound on port 6379 from the client’s security group. Test with:
valkey-cli -h <endpoint> -p 6379 --tls PINGIf TLS fails, try without TLS to isolate (note: serverless always requires TLS).
ssl=True and the correct CA bundle (Amazon root CA)setup/connectivity-diagnostics.md