Skip to content

feat(fetch): rate-limit backoff + enable auto-fetch by default (5min)#8

Merged
jcardonne merged 1 commit into
mainfrom
feat/rate-limit-backoff
Jul 12, 2026
Merged

feat(fetch): rate-limit backoff + enable auto-fetch by default (5min)#8
jcardonne merged 1 commit into
mainfrom
feat/rate-limit-backoff

Conversation

@jcardonne

Copy link
Copy Markdown
Owner

What

Makes background auto-fetch safe to ship on by default, per the rate-limit analysis.

Rate-limit reality

  • git fetch/pull/push ride the git protocol - a separate bucket from the REST/GraphQL API, effectively unlimited at a desktop cadence.
  • The API-bucket calls are the sidecars: gh pr list / glab mr list and avatar lookups (avatars are disk-cached w/ TTL).
  • Only the active + visible tab arms its interval, so multi-tab is not a multiplier - one fetch-stream max. At 5min that's ~12 API calls/hr vs GitHub's 5000/hr and GitLab's per-minute limits: a rounding error.

Changes

  1. Rate-limit backoff (src/util.ts + RepoView.tsx): backgroundFetch and refreshPrs recognise a provider rate-limit error (isRateLimited) and pause the background loop until it clears (rateLimitBackoffMs honours an explicit retry-after hint, clamped 30s..1h, else 15min). Toasts once on entering backoff. Foreground / user-initiated ops are never gated. This is the piece that stops on-schedule retries from prolonging a secondary limit.
  2. Default interval 0 -> 5min (storage.ts): users who explicitly picked "Off" have 0 stored and keep it; only never-configured users get the new default.

Notes / limits

  • Backoff keys off the error string (the CLI path gives no structured headers). Header-exact reset from the avatar ureq path is a possible future refinement.
  • Avatar 403s don't propagate (best-effort, cached), so they don't arm the backoff - acceptable given their low frequency.

Verify

  • New unit tests: isRateLimited (GitHub primary/secondary + GitLab 429; not plain 403/network) and rateLimitBackoffMs (retry-after parse + clamps + fallback) - 4 tests
  • 60 frontend tests green, tsc clean, build clean

https://claude.ai/code/session_01RVF5LSdTyciWKY1k5sedU8

Make background auto-fetch safe to have on by default. The active+visible tab
is the only one that fetches, so at 5min that's ~12 API-bucket calls/hr (PR
list + avatars) - a rounding error against GitHub's 5000/hr and GitLab's
per-minute limits. git fetch itself rides the git protocol, a separate,
effectively-unlimited bucket.

The realistic failure mode is a secondary/abuse limit (GitHub 403 + Retry-After,
GitLab 429), where retrying on schedule can prolong the block. So backgroundFetch
and refreshPrs now recognise a rate-limit error (isRateLimited) and pause the
loop until it clears (rateLimitBackoffMs honours an explicit retry-after hint,
else 15min), toasting once on entry. Foreground/user-initiated ops are never
gated by the backoff.

Default interval flips 0 -> 5min; users who explicitly chose "Off" keep it
(0 is stored), so only never-configured users get the new default.
@jcardonne
jcardonne merged commit 1d6b672 into main Jul 12, 2026
2 checks passed
@jcardonne
jcardonne deleted the feat/rate-limit-backoff branch July 12, 2026 21:44
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 0.30.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant