Knowing what is downloaded¶
Every delivered response is counted, per file, per hour, without touching the database on the request path.
How it works, and what it costs¶
A response bumps an in-memory counter; a background task writes the counters to the database every few seconds. Ten thousand downloads of one file in one hour cost one row and one update, rather than ten thousand inserts in front of the client.
That trade is deliberate and it is lossy: a process killed between flushes forgets its last few seconds. Statistics are for deciding what to cache and what to bill against, not for accounting, and paying a round trip per delivered byte range would be the wrong price for the difference.
Bytes are what actually reached the socket. A range request counts its range, and an abandoned download counts what it transferred — not the size of the file someone asked for.
Where to read them¶
| the zone list | a week of traffic per zone |
| the file browser | a month of downloads per file |
| a zone's Statistics page | a daily chart, the cache hit ratio, the busiest paths, and what could not be served |
| the API | the same numbers as JSON |
| the CSV button | a file to open in a spreadsheet |
curl -H "Authorization: Bearer $CDN_TOKEN" \
"https://cdn.example.com/_/api/v1/zones/assets/stats?days=30"
A token needs the stats scope to read them.
What the outcomes mean¶
| outcome | what happened |
|---|---|
hit |
served from the local cache |
miss |
fetched from S3 or the origin, then cached |
stale |
the origin was unreachable and an expired copy was served |
revalidated |
the client asked with If-None-Match and got 304 |
bypass |
a HEAD: neither a hit nor a miss, and counting it as either would flatter the ratio |
4xx, 5xx |
refused or failed; bytes are zero |
The hit ratio is over hit and miss only.
How long they are kept¶
Hourly rows are folded into daily ones after a month and dropped after a bit over a year, by the cdn rollup worker. A bucket is in exactly one of the two granularities, so a query that sums both cannot double-count.
One zone-hour gets rows for a bounded number of distinct paths; beyond that the rest are counted together under __other__. Anyone can invent URLs inside a real zone, and without a ceiling their invention would decide how many rows you store.