CloudFront distributions whose cache hit rate averages below 80% over 30 days
What does ZopNight detect here?
ZopNight reads the CloudFront `CacheHitRate` metric and flags distributions averaging below 80% over 30 days. The saving it would report is the measured cache-miss origin traffic priced at the per-GB rate, and because that byte count is not collected yet, ZopNight currently raises no finding rather than estimate a share of the bill.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1511 |
| Category | rightsizing |
| Severity | low |
| Metric | CacheHitRate |
| Threshold | < 80% average |
| Evaluation window | 30d |
| Source | ZopNight |
| Permissions used | cloudfront:ListDistributions · cloudfront:GetMonitoringSubscription · cloudwatch:GetMetricStatistics |
Every cache miss is a trip back to your origin
CloudFront defines the cache hit rate as the share of cacheable requests served from its own cache; POST and PUT requests and errors do not count as cacheable. Each miss makes CloudFront fetch the object from the origin, which adds origin load, latency for the viewer, and for origins outside AWS the egress your host bills you for.
AWS lists the usual causes on its
cache hit ratio page:
short cache durations, cache keys that include query strings, cookies or headers that vary per
request, and no Origin Shield layer in front of the origin. The shorter the max-age, the more
often CloudFront has to go back to check or refetch the object.
Turning on and reading CacheHitRate
CacheHitRate is one of the additional distribution metrics, which cost extra and are off until
you enable them per distribution. CloudWatch charges a fixed monthly rate for each of the up to 8
extra metrics. CloudFront metrics are only returned from us-east-1, with the Region dimension
set to Global:
aws cloudfront get-monitoring-subscription --distribution-id EDFDVBD6EXAMPLE
aws cloudfront create-monitoring-subscription --distribution-id EDFDVBD6EXAMPLE \ --monitoring-subscription RealtimeMetricsSubscriptionConfig={RealtimeMetricsSubscriptionStatus=Enabled}
aws cloudwatch get-metric-statistics --region us-east-1 --namespace AWS/CloudFront \ --metric-name CacheHitRate \ --dimensions Name=DistributionId,Value=EDFDVBD6EXAMPLE Name=Region,Value=Global \ --statistics Average --period 86400 \ --start-time 2026-08-26T00:00:00Z --end-time 2026-09-25T00:00:00ZWhat ZopNight checks on each distribution
- A
CacheHitRateseries exists. With additional metrics off there is no series, and ZopNight treats that as unknown, never as a 0% hit rate. - The series covers at least 7 days of hourly data.
- The 30-day average is below 80%.
- The distribution has a known monthly cost, and a measured dollar figure for the origin traffic its misses caused is available.
Why the rule is silent on every distribution today
The fourth input is missing. The request count and hit rate ZopNight collects do not say how many bytes the misses pulled from the origin, and without that number any saving would be a guess. So no recommendation appears, even for a distribution with a poor hit rate, until origin byte counts per distribution are collected. A distribution that serves no traffic at all is a different case, covered by Idle CloudFront Distribution.
How the saving will be priced
saving = cache-miss origin traffic in GB x CloudFront per-GB data transfer ratecapped at the distribution's monthly costNo flat percentage of the bill is ever used in place of the measured bytes.
Raising the hit rate
- Set a long
Cache-Control: max-ageat the origin for static objects, and raise the cache policy’s minimum and default TTLs to match. - Trim the cache key: forward only the query strings, cookies and headers that change the response.
- Turn on Origin Shield in the Region with the lowest latency to the origin so every caching layer goes through one extra cache. Origin Shield carries its own charge, so weigh it against the origin load it removes.
- Recheck
CacheHitRatea week later, since the average needs fresh traffic to move.