How to Track Your Cloudflare Cache Hit Ratio Over Time
Your cache hit ratio quietly decides how much traffic reaches your origin, and how much you pay for it.
It also regresses silently. A new Set-Cookie header, a changed Cache-Control, or a query string on every asset can cut it in half without anyone noticing until the origin bill arrives.
Two ratios, not one
| Ratio | Formula | Tells you |
|---|---|---|
| Request hit ratio | cachedRequests / requests |
How many requests never reached your origin |
| Bandwidth hit ratio | cachedBytes / bytes |
How much of the data served came from cache |
They move differently. A site with a few large, well-cached assets can have a high bandwidth ratio but a low request ratio because every uncached API call counts as a request. Track both.
Get the daily numbers
The httpRequests1dGroups dataset has everything you need, on every plan:
curl -s https://api.cloudflare.com/client/v4/graphql \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data "$(jq -n --arg zone "$ZONE_ID" --arg start "2026-08-01" --arg end "2026-08-31" '{
query: "query ($zoneTag: string, $start: Date, $end: Date) { viewer { zones(filter: {zoneTag: $zoneTag}) { httpRequests1dGroups(limit: 1000, filter: {date_geq: $start, date_lt: $end}, orderBy: [date_ASC]) { dimensions { date } sum { requests cachedRequests bytes cachedBytes } } } } }",
variables: { zoneTag: $zone, start: $start, end: $end }
}')" \
| jq -r '.data.viewer.zones[0].httpRequests1dGroups[]
| [ .dimensions.date,
(100 * .sum.cachedRequests / .sum.requests | floor),
(100 * .sum.cachedBytes / .sum.bytes | floor) ]
| "\(.[0]) requests: \(.[1])% bandwidth: \(.[2])%"'
Output:
2026-08-26 requests: 81% bandwidth: 93%
2026-08-27 requests: 80% bandwidth: 93%
2026-08-28 requests: 52% bandwidth: 71% <- something changed
You need a token with Zone → Analytics → Read. The date range can only go back as far as your plan’s retention.
Spotting a regression
A sudden, lasting drop is almost always a configuration change. The usual suspects:
Set-Cookieon static responses. Many setups skip caching when a response sets a cookie.Cache-Control: privateorno-storeadded by a framework upgrade.- Cache-busting query strings on assets that change every build or every request.
- A new Cache Rule (or a removed one) changing what’s eligible.
- More dynamic traffic. An API launch lowers the request ratio even though nothing broke.
Line up the date of the drop with your deploy history. That’s usually enough to find it.
Note: These fields measure cached requests at the zone level. Cloudflare’s Cache Analytics view breaks traffic down by cache status (hit, miss, dynamic, and so on) and may not match these numbers exactly. Use one source consistently for trends.
Why the trend needs history
A cache ratio is only meaningful compared to itself. “71%” means nothing; “71%, down from 93% last month” means someone should look.
- Seasonal comparisons. Was it this low during last year’s launch?
- Slow drift. A ratio that drops one point a month isn’t visible in a 7-day chart.
- Cost attribution. Origin egress bills lag. You’ll want the cache trend from before the bill arrived.
Run the query above monthly and append the results, or archive the data nightly to R2.
Keep the trend automatically
MetricKeeper archives your Cloudflare analytics, including cache metrics, from the day you connect. Spot a drop and compare it with any point in your history.