These rules flag ElastiCache clusters that are idle, running on a previous-generation node family, or running on-demand when reserved node pricing would save you money.
| Rule ID | Scan Type | Severity | Name |
|---|---|---|---|
| CLDBRN-AWS-ELASTICACHE-1 | Discovery | Medium | ElastiCache Cluster Missing Reserved Coverage |
| CLDBRN-AWS-ELASTICACHE-2 | Discovery | High | ElastiCache Cluster Idle |
| CLDBRN-AWS-ELASTICACHE-3 | Discovery and IaC | Medium | ElastiCache Cluster Node Type Not Current Generation |
CLDBRN-AWS-ELASTICACHE-1
ElastiCache Cluster Missing Reserved Coverage
Scan type: Discovery
Severity: Medium
What it checks
Flags ElastiCache clusters that have been running for at least 180 days without matching active reserved node coverage. The rule normalizes node sizes into capacity units and checks whether your reserved inventory covers each cluster's actual footprint.
Valkey clusters can consume reserved coverage from Valkey, Redis, or wildcard engine buckets. Node types with unknown sizes fall back to exact-type matching.
Why it matters
ElastiCache Reserved Nodes offer up to 55% savings over on-demand pricing for 1-year terms and even more for 3-year commitments. A cluster that has been running for 6+ months without reserved coverage is almost certainly a candidate for a reservation. The longer a cluster runs on-demand, the more money you leave on the table.
What triggers a finding
All of the following must be true:
- Cluster status is
available - Cluster has been running for 180 or more days
- Cluster node count is greater than zero
- The cluster's normalized capacity exceeds the remaining reserved node coverage for its
region:capacityKey:enginecombination, wherecapacityKeyis thecache.<family>prefix for node sizes AWS publishes normalized units for and the exact node type otherwise
When this rule reports a cluster, it supersedes the equivalent Cost Optimization Hub reservation-purchase finding (CLDBRN-AWS-COSTOPTIMIZATIONHUB-2) for the same cluster. See Finding Precedence.
How to remediate
- Review the flagged cluster's node type, engine, and node count
- Check your current reserved node inventory for gaps in coverage
- Purchase a reserved node that matches the cluster's configuration:
aws elasticache purchase-reserved-cache-nodes-offering \
--reserved-cache-nodes-offering-id <offering-id> \
--cache-node-count 1
Consider using the AWS Cost Explorer Reserved Instance recommendations to identify the most cost-effective reservation terms for your usage patterns.
CLDBRN-AWS-ELASTICACHE-2
ElastiCache Cluster Idle
Scan type: Discovery
Severity: High
What it checks
Flags available ElastiCache clusters whose 14-day average cache hit rate stays below 5% and average current connections stay below 2.
Why it matters
An ElastiCache cluster with negligible cache hits and almost no connections is not providing caching value. ElastiCache nodes are billed per hour regardless of utilization. A cache.r6g.large cluster costs roughly $200/month. If it's not being used, that's pure waste.
What triggers a finding
cacheClusterStatus is available AND averageCacheHitRateLast14Days is less than 5 AND averageCurrentConnectionsLast14Days is less than 2 (both non-null). Activity is joined to the cluster inventory by account, region, and cache cluster ID.
Coverage
An available cluster whose 14-day cache-hit rate or current-connections average is missing is reported as unknown rather than as a pass. See Live Evaluation Coverage.
How to remediate
Verify that the application is configured to use the cluster. If the cluster is genuinely unused, delete it. If it's supposed to be used, investigate why the application isn't connecting (wrong endpoint, DNS mismatch, security group blocking).
aws elasticache delete-cache-cluster --cache-cluster-id my-cluster-id
CLDBRN-AWS-ELASTICACHE-3
ElastiCache Cluster Node Type Not Current Generation
Scan type: Discovery and IaC
Severity: Medium
What it checks
Flags ElastiCache clusters still running on a previous-generation node family. The reviewed families are cache.t1, cache.t2, cache.m1, cache.m2, cache.m3, cache.m4, cache.c1, cache.r3, and cache.r4. Each has a current-generation successor with better price performance.
Why it matters
Previous-generation cache nodes deliver less memory bandwidth and network throughput than the current-generation node that replaces them, usually at a similar hourly rate. The gain is performance per dollar and access to reserved-node pricing rather than an automatic lower bill: a same-size move such as cache.m4.large to cache.m7g.large is roughly price-neutral on demand in us-east-1. Compare the on-demand and reserved rates for your engine and Region before migrating.
What triggers a finding
In discovery scans, the cluster status is available and its cacheNodeType parses as cache.<family>.<size> with a family in the previous-generation set. In IaC scans, the declared node type parses the same way, with no status check.
How to remediate
Modify the cluster to a current-generation node type. Graviton families (cache.m7g, cache.r7g, cache.t4g) give the best price/performance:
aws elasticache modify-cache-cluster \
--cache-cluster-id my-cluster-id \
--cache-node-type cache.m7g.large \
--apply-immediately
For Redis and Valkey replication groups, modify the replication group instead and let ElastiCache replace nodes one at a time to avoid downtime. Check that your engine version supports the target family before applying.
IaC resources checked
| IaC Tool | Resource Type |
|---|---|
| Terraform | aws_elasticache_cluster |
| Terraform | aws_elasticache_replication_group |
| CloudFormation | AWS::ElastiCache::CacheCluster |
| CloudFormation | AWS::ElastiCache::ReplicationGroup |
See Also
- CLI discover command -- scan live ElastiCache clusters
- CLI scan command -- scan IaC templates for ElastiCache issues
- SDK Reference -- run scans programmatically