My GitHub profile said Something went wrong where the contribution graph should have been. The activity timeline underneath it was empty too.
Two explanations arrive uninvited when that happens. Either something is wrong with my account, or GitHub is having an outage. Both are worth ruling out before you start refreshing and hoping, because they imply completely different responses — and as it turned out, neither was true.
What follows is the whole diagnosis. It took about five minutes and three queries, and the method generalises well past this particular breakage.
Find the actual request behind the broken thing
A rendered page that fails tells you almost nothing. You want the specific call it makes.
The contribution graph is drawn from contributionsCollection in GitHub's GraphQL API, so I asked for it directly:
gh api graphql -f query='{
user(login: "your-account") {
contributionsCollection { contributionCalendar { totalContributions } }
}
}'
That returned 502 Bad Gateway after about 11 seconds. Three attempts, three 502s.
This is already worth something. A reproducible 502 with a long latency is a server-side timeout, not a browser problem — which means refreshing, clearing cache, and trying another browser are all guaranteed to waste your time. I stopped doing any of that immediately.
But "one query is slow" doesn't yet tell me whether my account is broken.
Control 1: is the account itself healthy?
Ask the same account for something trivial:
gh api graphql -f query='{ user(login: "your-account") { login createdAt } }'
Instant response. The account resolves, the record exists, GraphQL is happy to talk about it.
So the account isn't damaged or suspended. Whatever is failing is specific to the expensive query, not to me as a user. One suspect eliminated.
Control 2: is GitHub itself down?
Run the same expensive query against a different account. I used Linus Torvalds, because it's a public account with a lot of activity and the query is read-only:
gh api graphql -f query='{
user(login: "torvalds") {
contributionsCollection { contributionCalendar { totalContributions } }
}
}'
Returned fine.
This is the control that matters most, and it's the one people skip. Same endpoint, same query shape, different input — and it works. So the aggregation machinery is up. The failure needs my data to happen.
Second suspect eliminated. By now I know the problem lives in the intersection of this query and this account, which is a much smaller place to look than "GitHub is broken."
Control 3: shrink the input until it works
The default contributionsCollection window is a trailing year. So I asked for a week:
gh api graphql -f query='{
user(login: "your-account") {
contributionsCollection(from: "2026-07-12T00:00:00Z", to: "2026-07-19T00:00:00Z") {
totalCommitContributions
totalPullRequestContributions
restrictedContributionsCount
}
}
}'
It returned immediately: 2,024 contributions in seven days — 560 commits, 541 pull requests, 457 in private repositories.
That single response answers both remaining questions at once.
The failure is a function of window size, so it's an aggregation timeout — the backend can't finish summing a year of this account's activity inside its own limit. And the underlying data is intact, because a seven-day slice of it just came back with real numbers in it. Nothing is corrupt or missing. Only the summing-up is failing.
A view that won't render and data that's gone are different problems, and one query tells them apart.
That distinction was the whole point of the exercise. If the data had been damaged I'd have had an urgent problem. Instead I had a cosmetic one, and I could go back to work.
Why it happened, and what I did about it
The cause is unglamorous: the day before, I'd pushed an unusually heavy burst of work across a lot of repositories at once. A trailing-year aggregation over a high-activity account spanning dozens of repos — private ones included — is simply an expensive thing to compute, and that burst pushed it past whatever budget the backend allows.
I want to be careful here, because I can't see GitHub's internals. That's the explanation most consistent with the evidence I have — window size determines failure, other accounts are unaffected — not something I confirmed from the inside.
What I did about it: nothing.
That was the actual decision, and it was only available to me because of control 3. Once you know the data is fine and the failure is a load-shaped timeout on a view, the correct response is to leave it alone and let the aggregation get cheaper as the burst falls out of the trailing window. There was no fix to apply. There was a wrong action available — filing a support ticket about data loss, or worse, "repairing" something — and skipping it was the win.
Eleven days later I ran the same year-long query again. It came back in 2.3 seconds with 21,253 contributions. It healed exactly the way the evidence said it would.
The method, minus my specific problem
Three questions, in this order, each answerable with one call:
Does a cheap request to the same subject work? If yes, the subject is fine and you're looking at a query problem, not an account problem.
Does the same expensive request work for a different subject? If yes, the service is fine and the failure needs your particular data.
Does the expensive request work on a smaller input? If yes, it's a scale or timeout issue — and crucially, you have just proved the data underneath is readable.
None of that is clever. What makes it useful is that each answer eliminates an entire class of cause, so five minutes of it beats an afternoon of refreshing the page and reading status pages that say all systems operational.
And the third question does double duty: it's the one that tells you whether you're facing an emergency or an inconvenience. That's usually the thing you actually need to know first.
What's the last "everything is broken" you had that turned out to be one query being asked for too much at once?
── Hideyuki Mori (Ayane International) 🔗 hideyuki-mori.com
Top comments (0)