Cache hit ratio is lying to you: measure byte offload

Request-hit ratio and byte-hit ratio diverge on adult portals, and origin shielding distorts both. Here is why byte offload is the metric that actually predicts cost and QoE.

THE PROBLEM The dashboard says 96% cache hit ratio, but origin egress and cost keep rising.

LAST REVIEWED

A single number on a delivery dashboard can be technically true and operationally useless. Cache hit ratio is the most common example: adult portals routinely report mid-to-high 90s request-hit ratios while origin egress climbs. The ratio is not wrong — it is measuring the wrong traffic, and on a video-heavy adult platform that is the only traffic that costs real money.

The mechanism: requests and bytes are different populations

On a typical adult portal, images are the overwhelming majority of requests but a minority of bytes; video is the overwhelming majority of bytes but a minority of requests. Public traces of a large portal show roughly 80% of requests were images against roughly 37% of bytes, and roughly 20% of requests were video against roughly 63% of bytes. A request-hit ratio weights every image request equally with every video segment, so it is dominated by the cheap traffic. You can score 96% and still be forwarding most of the expensive bytes.

Request-hit ratio answers: “what fraction of lookups did the cache answer?” Byte offload answers: “what fraction of delivered bytes came from cache?”

Only the second one correlates with origin egress, delivered cost, and (on seek-heavy video) QoE.

Cause 1: video is a small request share and a large byte share

Because video requests are few and large, a 5% request miss rate can be a 40% byte miss rate if the misses are video. Range misses make this worse: a single full-object origin fetch on a seek can dwarf hundreds of image hits in bytes. Report cache metrics split by content class — image, video, manifest, API — so video miss bytes cannot hide inside image hit volume.

Cause 2: shielding distorts hit ratio in both directions

An origin shield changes what “hit” means. With a shield, edge misses that are served by the shield are counted as hits at the edge, while the shield’s own miss rate is the real origin exposure. If you compute one ratio across both tiers, the shield inflates the number and hides origin egress. Measure at each tier separately: edge byte offload, shield byte offload, and — the number that actually bills — origin bytes.

Cause 3: purges and cold fills pollute the window

A hard purge or a promotion cold-fill produces a burst of misses that a long averaging window smooths away. Conversely, a short window after a purge can look catastrophic. Track byte offload with a stable window and annotate purge/pre-warm events so the ratio is interpreted, not just read.

Cause 4: status codes and partial responses are miscounted

206 Partial Content and 304 Not Modified are frequently excluded from cache-hit calculations, or counted inconsistently. On a range-heavy video platform, excluding 206 removes exactly the responses that matter. Count them, and verify from logs that 206 responses are served from cache rather than proxied from origin. RFC 9211 (Cache-Status) exists precisely so a response can report which tier served it and whether it was a hit, fwd, or revalidated — use it as the authoritative signal instead of inferring from status codes.

What to measure instead

MetricDefinitionWhy it matters
Byte offloadCached bytes ÷ total bytes, per class and per tierDirect proxy for origin egress avoided
Origin bytesBytes leaving origin per periodThe number on the bill
Video byte missOrigin video bytes ÷ total video bytesIsolates the expensive misses
Range hit rate206 served from cache ÷ 206 totalSeek-side QoE and egress
Shield fill ratioOrigin fetches collapsed ÷ edge missesShield effectiveness

Report these per region and ASN, because a global average hides a bad peering path or a region with no shield.

What good looks like

  • Byte offload, not request-hit ratio, is the headline cache KPI.
  • Metrics are split by content class and measured per cache tier.
  • 206 responses are counted and proven to be cache hits.
  • Cache-Status headers are trusted over inferred status-code logic.

How to prove it

Instrument both ratios on the same hostname, then route a small slice through a tuned path and compare byte offload and origin bytes against the incumbent. This is a controlled test that requires no migration and settles the argument with data.