// Guides2026-08-315 min read

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-Cookie on static responses. Many setups skip caching when a response sets a cookie.
  • Cache-Control: private or no-store added 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.

Get Early Access →

Sources