## TL;DR
GitHub's secondary rate limits trigger on abusive patterns, not just request counts: too many concurrent requests, rapid content creation, or expensive queries in a burst during incident triage. Back off exponentially when you hit one, serialize the requests that triggered it, and cache aggressively so the agent never needs the burst in the first place. Retrying through a secondary limit without backing off extends the ban.

```text
secondary rate limit
```

## Steps

1. Detect the secondary limit explicitly and stop the burst immediately.

```bash
curl -s -H 'Accept: application/vnd.github+json' https://api.github.com/rate_limit | python3 -m json.tool | grep -i -E 'limit|remaining|reset'
```

Expected: the rate-limit payload. A secondary limit often shows as remaining requests with a retry-after hint; treat any 403 with a secondary-limit message as a full stop, not a retry.

2. Back off exponentially with jitter, and do not retry the same burst shape.

Expected: waits doubling from tens of seconds, with jitter. The critical change is serializing what was parallel: one request at a time until the limit clears.

3. Find which call pattern triggered it in the agent's recent request log.

Expected: usually a fan-out like "fetch every open PR's checks concurrently" or polling a workflow run every few seconds. That pattern gets rewritten, not just slowed down.

4. Cache GitHub responses for the incident's duration and poll on a sane interval.

Expected: the agent reads PR and check state from a cache refreshed every 60 to 120 seconds instead of hammering the API. Triage stays fast because the data is local; the API sees a trickle.

## When to use

- An agent hits secondary rate limits while triaging an incident that involves GitHub (failed checks, PRs, workflow runs).
- You are building the GitHub tool calls an agent uses during incidents.
- After any incident where GitHub access degraded because of the agent's own traffic.

## When not to use

- The primary rate limit is the problem (that is a quota issue; add auth or reduce calls, different fix).
- A human is clicking through the GitHub UI (humans rarely trigger secondary limits).
- The 403 is from a missing permission, not rate limiting (that is an auth scope problem).

## Why it happens

Secondary limits exist to stop patterns that hurt the API: many concurrent requests from one source, rapid-fire mutations, or long expensive queries repeated quickly. Incident triage is exactly the workload that produces these patterns: the agent fans out to check every PR, every check run, every workflow, all at once, right when it is most impatient. The primary limit counts requests; the secondary limit judges behavior.

## Edge cases

- Authenticated requests get higher limits, but an unauthenticated or poorly-scoped token in the agent burns the shared budget fast; check which credential the agent uses.
- GraphQL lets the agent fetch PR plus checks plus reviews in one call; one GraphQL query replaces a fan-out of REST calls.
- Webhooks beat polling: subscribe to check-run events instead of polling workflow status in a loop.
- The ban duration grows with repeated violations; the first backoff is cheap, the fifth one ruins the incident.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_0GLVajI0kyJ06gBf3Yp8OQ
