Skip to content

fix: report the real API rate-limit budget from response headers - #26

Merged
JustMaris merged 1 commit into
mainfrom
fix/rate-limit-headers
Oct 4, 2026
Merged

JustMaris merged 1 commit into
mainfrom
fix/rate-limit-headers

Conversation

@JustMaris

Copy link
Copy Markdown
Member

github_rate_limit_remaining sat at 5000/5000 almost permanently: over 7 days it dipped only once, to 4962. That's because GET /rate_limit reports used: 0 for our tokens. The headers on ordinary API calls showed the real count at the same time, e.g. used: 1210. As a result, GithubApiRateLimitLow could never fire.

What GitHub is doing

According to GitHub's REST rate-limit docs:

  • Requests are processed in several regions, so "rate limit values can vary from one response to the next".
  • The x-ratelimit-* headers are authoritative over /rate_limit.

Measured with one token, it's counted in two core windows at once, each with its own reset time and count:

Endpoints Window reset Remaining
/orgs/{o}/actions/runners, /repos/{r}/actions/workflows, /repos/{r}/dependabot/alerts 17:43 UTC ~3,495
everything else tried (/user, /orgs/{o}, repos, pulls, issues, commits, /actions/runs, contents) 18:12 UTC ~4,865

Changes

  • The client records the X-RateLimit-Limit/Remaining/Reset headers of every core response and keeps one entry per window (keyed by reset time). Within a window it keeps the lowest count seen. Windows drop off once they reset.
  • github_rate_limit_remaining / _limit now report the scarcest active window, the one that runs out first, so the alert and dashboard need no changes. They're read at scrape time from the client, so the 15s runner poll keeps them fresh. They were previously part of the 5-minute org snapshot.
  • New github_rate_limit_window_remaining{reset}: one series per active window.
  • The dashboard's rate-limit-over-time panel also plots each window.
  • The /rate_limit call is gone, which saves one request per org refresh.

Verification

  • go test -race ./... passes. The new client test covers two concurrent windows, a non-core resource being ignored, and window expiry.
  • Local run against drumandbytes: github_rate_limit_window_remaining{reset="17:43:05Z"} 3367 and {reset="18:12:54Z"} 4797. Live headers moments later read 3365 and 4796, and github_rate_limit_remaining = 3367.

GET /rate_limit reported used=0 for our tokens, so github_rate_limit_remaining
sat at 5000 and the low-budget alert could never fire. Read X-RateLimit-* from
every API response instead, as GitHub documents. GitHub counts per region, so
one token can be in several core windows at once: track each by reset time,
report the scarcest as github_rate_limit_remaining, and expose every window as
github_rate_limit_window_remaining{reset}. Drops one request per org refresh.
@JustMaris
JustMaris enabled auto-merge (squash) October 4, 2026 17:18
@JustMaris
JustMaris merged commit 3ac76f2 into main Oct 4, 2026
8 checks passed
@JustMaris
JustMaris deleted the fix/rate-limit-headers branch October 4, 2026 17:20
@dnb-robot dnb-robot Bot mentioned this pull request Oct 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant