-
Notifications
You must be signed in to change notification settings - Fork 0
Understanding the Statistics
GitHub exposes a cumulative download_count for each file attached to a release. GitHub Downloads Action converts those current counters into a dated total series, then derives rolling changes from earlier snapshots.
For a run on UTC date d, the total is:
total(d) = sum of download_count for every release asset returned by GitHub
If a release has three attached files, downloads of all three contribute to the total. One person downloading two assets contributes two asset downloads. The value does not represent unique users.
For a range of k days, the action uses:
range(k, d) = max(0, total(d) - baseline(d - k))
The published fields use k = 1, 7, and 30:
| Field | Intended baseline |
|---|---|
stats.day |
Total one UTC date earlier |
stats.week |
Total seven UTC dates earlier |
stats.month |
Total thirty UTC dates earlier |
When an exact baseline date exists, the corresponding partial flag is false. When it does not exist, the action uses the nearest available snapshot and marks the result as partial.
partial.day, partial.week, and partial.month describe baseline coverage, not whether the action failed.
-
falsemeans an exact snapshot was available on the required baseline date. -
truemeans the range is still warming up or contains a date gap, so the value uses the best available baseline.
A normal daily schedule typically develops coverage in this order:
| Snapshot history | Day | Week | Month |
|---|---|---|---|
| First run | Partial | Partial | Partial |
| After two daily dates | Exact when consecutive | Partial | Partial |
| After eight daily dates | Exact when consecutive | Exact when consecutive | Partial |
| After thirty-one daily dates | Exact when consecutive | Exact when consecutive | Exact when consecutive |
Missing scheduled runs can make a range partial again because the required calendar date is absent. A range value may still be useful, but it should not be presented as an exact interval count while its flag is true.
window_days controls how many UTC dates remain in snapshots.series. The default is 45, which retains enough history for all three standard ranges when the workflow runs consistently. Reducing the window below 31 days prevents reliable thirty-day baselines.
Only one total is retained for each UTC date. Running the hourly profile refreshes the current day's snapshot more often, but it does not create hourly history or an hourly download metric. profile.defaultMode records whether the selected workflow profile is daily or hourly.
The action polls the current release asset counters. It does not maintain a permanent ledger of individual download events. Deleting a release or replacing an asset can remove its counter from later API totals. When a current total is lower than a baseline, the published range delta is clamped to zero rather than becoming negative.
For this reason, the series should be interpreted as snapshots of the repository's currently visible release asset counters. It is well suited to README badges and rolling project indicators, but it is not a substitute for event-level analytics or unique-user measurement.
{
"schemaVersion": "1",
"owner": "OWNER",
"repo": "REPOSITORY",
"visibility": "public",
"generatedAt": "2026-08-25T03:00:00.000Z",
"stats": {
"total": 9412,
"day": 16,
"week": 159,
"month": 802
},
"partial": {
"day": false,
"week": false,
"month": false
},
"snapshots": {
"windowDays": 45,
"count": 45,
"firstDate": "2026-07-12",
"lastDate": "2026-08-25",
"series": {
"2026-08-25": 9412
}
},
"profile": {
"defaultMode": "daily",
"hourlyEnabled": false
}
}The normative structure is defined by the repository's JSON Schema.