What the Green Squares on GitHub Actually Measure
GitHub's contribution graph counts commits, issues, and pull requests tied to a verified email — not code quality, difficulty, or even most of a developer's real work, and it can be faked with a five-line script.
In this article5 sections
GitHub’s contribution graph counts commits, opened issues, opened pull requests, and pull request reviews tied to an email address connected to your account — nothing about how good, how hard, or how useful any of that work was. It has become one of the most widely trusted-and-distrusted signals in software hiring, and both reactions are earned, because the graph was never built to be evidence of anything beyond activity.
(Disclosure: I write for DontSnooze, a social-accountability app that works nothing like a public activity graph. What follows is about GitHub’s own choices, on their own terms.)
What actually turns a square green
By default, the graph shows public-repository activity only. A developer can opt in to show private-repository activity too, but GitHub anonymizes the specifics — collaborators can see what was actually done; the public sees only that something happened, on some private repo, at some point that day. The graph also silently drops anything authored under an email address that isn’t linked to the account, which is the single most common reason a developer’s “real” work history looks thinner than it was: years of commits under a work email nobody ever connected.
That’s a narrower definition than most people assume they’re looking at. An architecture review that reshapes a whole codebase, a two-hour debugging session that ends with a one-line fix, a Slack thread that unblocks three other engineers — none of it touches the graph unless it lands as a commit, an issue, a pull request, or a review, authored under a recognized address. The squares track a specific, countable slice of software work, not software work in general.
Why the graph became a status symbol anyway
A grid of squares is legible in a way a resume bullet isn’t — you can see a year of activity in one glance, which makes it an easy shortcut for a busy reviewer. That legibility is also what turned it into something developers started managing for its own sake rather than as a byproduct of their actual work. Multiple public teardowns have walked through exactly how easy the graph is to fool: an empty commit at midnight, timed by a cron job, is enough to keep a streak alive with zero real work behind it, and at least one widely shared writeup (“I Hacked GitHub’s Contribution Graph. Here’s How Embarrassingly Simple It Was.,” posted to Medium) documents doing precisely that as a demonstration of the gap between the signal and the substance it’s assumed to represent. A separate DEV Community piece, pointedly titled “Your GitHub Contribution Graph Means Absolutely Nothing — And Here’s Why,” makes the same case from the other direction: engineers at banks, hospitals, and government agencies routinely write large amounts of consequential code that never touches a public GitHub repo at all, so an empty graph can just as easily mean “works somewhere with different infrastructure” as “doesn’t code.”
Once a metric is known to be gameable and known to be watched, some number of people will optimize the metric instead of the work — that’s true of graphs, of step counters, and of workplace productivity dashboards alike, and GitHub’s version happens to be unusually visible because it sits on a public profile page anyone can screenshot.
The part that’s easy to miss: this is loss aversion with a calendar attached
Daniel Kahneman and Amos Tversky’s 1979 prospect theory paper (Econometrica 47, no. 2) found that people weigh a loss roughly twice as heavily as an equivalent gain — losing something you already have hurts more than never having gained it helps. A contribution streak converts ordinary daily effort into something that can be “lost,” and once a developer has fifty or two hundred green days in a row, the emotional stake isn’t really “should I write code today” anymore — it’s “am I willing to lose the streak,” which is a different, and often stronger, question. That’s a real behavioral lever, and it’s also exactly the lever a five-line script can pull without anyone doing any work at all: the graph can’t tell the difference between a genuine loss-averse developer protecting real momentum and someone protecting a number.
What a public activity graph can’t do that a private group chat can
A contribution graph has no witness who knows the context — a viewer sees a green square and has to guess what it represents, and the guess is usually more generous than the reality. It also has no cost for a gap: a red week just sits there, unremarked on, unless someone happens to be looking at the right day on the right profile. Compare that to a small group actually watching in real time, where a missed day gets noticed the same day, by people who know what the goal was supposed to be — that’s a difference in kind, not just in audience size, and it’s the reason a public graph and a private accountability group solve different problems even though both produce a visual record of consistency. A framework for scoring how fakeable different accountability signals really are puts an unwitnessed, self-reported activity log — which is what a contribution graph is, whatever else it looks like — near the bottom of that list, for the same reason an empty commit at midnight works: nobody downstream is checking whether the square represents anything real.
Where this critique overreaches
None of this means the graph is useless — a completely empty profile combined with claimed years of experience is still a mismatch worth asking about, and a graph with real texture (varied repos, real pull request discussion, contributions to projects a reviewer can actually inspect) is harder to fake convincingly than a bare streak of green squares. The critique here is narrower than “ignore the graph entirely.” It’s that a streak, by itself, answers a much smaller question than the one most people reading it think they’re asking.
Zoom out from GitHub specifically and the same question applies to any unwitnessed-tracking method: a ranked comparison of how those methods hold up when no one’s checking puts the graph’s particular failure mode in a wider, less flattering context.