Code Review That Teaches
Updated: Oct 18
Ask developers why they review code and most will say: to find bugs. In 2013, Alberto Bacchelli and Christian Bird studied code review at Microsoft. They surveyed developers and managers, interviewed and observed reviewers, and classified 570 real review comments. Finding defects was the top motivation people gave. In the comments, defects were only the fourth most common category, at 14%. The most common, at 29%, was code improvements: better practices, removing unneeded code, readability. The researchers also found that reviews delivered knowledge transfer, team awareness and better solutions, and that "context and change understanding is the key of any review."
Google's 2018 study of nine million reviewed changes reached a compatible conclusion from another direction. Developers there described code review partly as an educational tool, and the data fit: the longer an author had been at Google, the fewer comments their changes received.
So review already does most of its work as a way of sharing knowledge. The question for a team isn't whether review should teach, but whether yours does, and for whom. In many teams the honest answer is: it teaches the two senior engineers who do most of the reviewing what everyone else is building, and teaches everyone else which nits those two care about.
The running example
(Composite.) A product team of nine engineers ships about 60 pull requests a month. The engineering manager pulls three months of review data and finds:
Two senior engineers did 74% of all reviews.
The payments module had one reviewer for every change in the period. If she left, nobody else had read that code recently.
Of 40 review comments sampled at random, 19 were about formatting or naming, 4 explained why a change was needed, and 2 were questions.
The median wait for a first review was 26 hours.
Nothing here looks broken from the inside. Every PR was reviewed, every comment was addressed, and nothing obviously bad was merged. But the reviews weren't spreading knowledge, the comments weren't teaching, and one module depended on one person.
The test: pull your last three months of merged PRs and count who reviewed them. If you use GitHub, this lists the size and reviewers of each PR:
gh pr list --state merged --limit 200 --json additions,deletions,reviews \
--jq '.[] | [(.additions + .deletions), ([.reviews[].author.login] | unique | join(","))] | @tsv'
Count the share of reviews done by the top two people, and for each important directory, how many different people reviewed changes to it. A directory with one reviewer is a knowledge silo, however good the reviews are.
Look at what your comments actually say
The fastest diagnostic is to read your own review comments. Sample 30 or 40 from recent PRs and sort them into a few kinds: style and formatting, requests to change something without a reason, explanations of why, questions, and praise. A team whose reviews teach has a good share of the last three. A team whose reviews gate has mostly the first two.
Style comments are the cheapest to remove, because a machine can make them. Formatters and linters in CI settle formatting and naming rules before a human looks. Every style comment a human writes is attention not spent on design, correctness or explanation.
Then rewrite the comments that remain. The difference between a comment that gets compliance and one that teaches is usually one sentence of reasoning.
Gates | Teaches |
"Use a map here." | "suggestion: a map here signals you're transforming each item with no side effects, which makes the loop's intent obvious and stops someone adding a mutation later." |
"Move the fetch to the parent." | "question: what made you fetch here rather than in the parent? If it's to avoid the parent's re-renders, that's worth a comment in the code." |
"This is wrong." | "issue (blocking): amount is a float, so 0.1 + 0.2 won't equal 0.3. Money needs integer cents or a decimal type. The pricing module has a helper for this." |
(no comment) | "praise: good call handling the timeout separately from the error case. That's the one people usually miss." |
The question form matters more than it looks. It either surfaces a gap the author fixes, or reveals context the reviewer didn't have. Either way someone learns something, and nobody has to defend a position.
The test: sample 30 recent review comments. Count how many contain a reason (a "because", a "so that", a consequence). If fewer than a third do, the reviews are mostly telling people what to change, not why, and the same comments will recur on the next PR.
Label every comment by weight
Unlabelled comments all feel like requirements. Authors either address everything, including trivial preferences, or start pushing back on everything, including real problems. A label fixes that in a word.
Two conventions are widely used. Google's engineering practices guide tells reviewers to prefix polish with "Nit:" so authors know it's optional. Conventional Comments goes further, with a label and an optional decoration on every comment:
<label> [decorations]: <subject>
[discussion]
The labels include praise, nitpick, suggestion, issue, question, thought and todo, and the decorations include (blocking), (non-blocking) and (if-minor). "issue (blocking): this concatenates user input into SQL" and "nitpick (non-blocking): I'd call this userCount" can't be confused.
Labels also make the review itself measurable. You can count praise, questions and blocking issues per PR, and see whether the mix changes over time. Google's guide adds a rule worth adopting with them: approve a change once it definitely improves the overall health of the code, even if it isn't perfect. Comments meant purely to teach are welcome, as long as they're marked as not blocking.
The test: after two weeks of labelled comments, count the blocking ones. If most PRs have none and still take a day to merge, the delay isn't coming from problems in the code. Look at review latency and PR size instead.
Make it fast enough to teach
Feedback teaches best while the author still remembers why they wrote the code. A review that arrives two days later lands on someone who has moved on, and it gets addressed mechanically.
Google's study gives a reference point: a median wait for first feedback of under an hour for small changes, about five hours for very large ones, and under four hours for the whole review process. The same study found the median change modified 24 lines, more than 35% of changes touched a single file, and about 90% touched fewer than ten. Small changes and fast reviews go together. A reviewer can understand 24 lines properly in one sitting, and understanding, as the Microsoft study found, is the whole job.
Your numbers don't need to match Google's. They need to be measured. Track the median time to first review and the median PR size, and keep both visible.
The test: compute your median PR size and median time to first review for the last month. If PRs are routinely hundreds of lines, the most effective review improvement is a change to how work is split, not to how reviews are written. Measuring review health walks through setting these up.
Spread the reviewing deliberately
If the same two people review everything, review teaches them a lot and everyone else very little. The fix is to add reviewers, not to remove the seniors.
Add a learning reviewer. For changes to a critical area, add a second reviewer from outside it, explicitly as a learner. Their job is to understand the change and ask questions, not to approve it. Their questions are often the ones that expose assumptions the author and the usual reviewer share.
Have juniors review seniors. A junior engineer reviewing a senior's change learns the patterns and reasoning by reading them closely. A senior's job in that review is to answer the questions well.
Rotate ownership of silos on purpose. For each area with a single reviewer, name a second person and route a share of its reviews to them for a quarter.
In the example: the team adopted labelled comments, moved formatting and naming to CI, and added a learning reviewer to every payments change. After six weeks, style comments in a fresh sample of 40 fell from 19 to 3, comments with a reason rose from 4 to 15, payments had three regular reviewers instead of one, and the top two engineers' share of reviews fell to about half. Median time to first review dropped to 9 hours, partly because more people were reviewing.
The test: for each directory that matters, count distinct reviewers in the last quarter. Any area with one is a priority for a learning reviewer this month.

Reviewing AI-generated code: understanding is the point
AI coding assistants change one assumption code review has always relied on: that the author understands the code they're submitting. When a large share of a change was generated, the author may be reviewing it for the first time alongside the reviewer.
That makes the Microsoft finding more important, not less. If understanding is the core of review, a change that nobody fully understands hasn't been reviewed, however many approvals it has. Two practices help.
Ask the author to explain it back. For any change with substantial generated code, the description should say in the author's own words what it does, why this approach, and what was checked. A reviewer who asks "walk me through how this handles a retry" and gets a vague answer has found the real problem.
Review for what generated code tends to skip: error paths, boundary cases, security-sensitive handling and consistency with the rest of the codebase. What AI-generated code structurally skips covers these patterns, and reviewing AI-generated code turns them into a review routine.
Automated reviewers can take over some of the mechanical comments, the same way linters did. That frees human review for the parts that teach: design, intent and the reasons behind them.
The test: pick a recent PR with substantial generated code and ask its author to explain one non-obvious section without looking at it. If they can't, the team needs the explain-back rule before it needs a better tool.
What to do this week
Run the reviewer count for the last three months and find your single-reviewer areas. Sample 30 recent comments and count the ones with a reason. Then make three changes: move every style rule you can into CI, adopt comment labels (Conventional Comments or a simple "Nit / Suggestion / Blocking"), and add a learning reviewer to the most siloed area. Measure the same three numbers again in six weeks.
Final takeaway
Research at Microsoft and Google found that code review delivers more knowledge transfer and code improvement than defect-finding, and that understanding the change is the heart of it. A review process that only gates wastes most of that. Read your own comments, label them, give every comment a reason, keep changes small and reviews fast, and spread reviewing beyond the people who already know the code. With AI writing more of it, make sure somebody understands every change before it merges.
Sources
Bacchelli, A. and Bird, C., "Expectations, Outcomes, and Challenges of Modern Code Review", Proceedings of ICSE 2013, 712–721: 570 comments classified at Microsoft; code improvements 29% (most frequent), defects 14% (fourth); "context and change understanding is the key of any review." https://doi.org/10.1109/ICSE.2013.6606617
Sadowski, C., Söderberg, E., Church, L., Sipko, M. and Bacchelli, A., "Modern Code Review: A Case Study at Google", ICSE-SEIP 2018: 9 million reviewed changes; median 24 lines modified; over 35% of changes touch a single file and about 90% fewer than 10; median first feedback under an hour for small changes; overall median review latency under 4 hours; comments per change fall with author tenure, which the authors read as support for review's educational role. https://research.google/pubs/modern-code-review-a-case-study-at-google/
Google, "The Standard of Code Review" (Google Engineering Practices): approve once a change definitely improves overall code health; prefix polish with "Nit:"; educational comments are welcome when marked as not critical. https://google.github.io/eng-practices/review/reviewer/standard.html
Conventional Comments: labels (praise, nitpick, suggestion, issue, question, thought, todo, chore, note) and decorations (blocking, non-blocking, if-minor). https://conventionalcomments.org/
Related reading
Keep learning. This article is part of the Advanced Quality Engineering path in the ShiftQuality Learning Center. Take quality from a team chore to an organizational property.


