Essay
Reviews worth the interruption
How authors and reviewers can make pull requests easier to review
The interruption
A code review usually begins with a pull request and an interruption. Someone has to stop what they are doing, find enough context to understand the change, and follow the author’s logic. When the pull request leaves an important question unanswered, the conversation is necessarily asynchronous. By the time an answer arrives, both people may have to recover that context again.
It’s no surprise that we sometimes have difficulty finding someone to review our code.
The author may have spent days working through the problem, considering alternatives, and deciding how to implement a change. The reviewer gets a diff. They have to work backward from the code to understand the problem, the decisions that were made, and whether the result makes sense.
A review isn’t a favor we ask after the important work is finished. It’s part of the important work. We ask another person to look for problems we may not see, question decisions that worry them, and tell us whether the change fits the code around it.
A good review happens in three stages. First, the author makes the change understandable and explains why it matters. Second, the reviewer examines the change in context and offers useful feedback. Finally, the author considers that feedback, reexamines their decisions, and improves the code where needed.
We can make that work easier on the reviewer — and easier on ourselves.
Show the change
Small pull requests are usually easier to review. There’s less to read, less to remember, and less opportunity for unrelated changes to obscure the work. But small isn’t a measurement of a good pull request.
A feature may require replacing a library and changing all the code that uses it. The resulting diff might be large, but it represents one decision. Splitting it into several pull requests just to make each one smaller can leave reviewers mentally reconstructing the complete change across multiple reviews.
On the other hand, a library replacement that can be completed independently might be worth reviewing separately. Unrelated renames and formatting changes should probably stay out of the way. The question isn’t how many lines changed. It’s whether the reviewer can understand what changed and why.
The description and the code have different jobs. The description explains the change; the code has to stand up to inspection. A good pull-request description gives the reviewer somewhere to start. What problem are we solving? What behavior should change? What should remain the same? Are there constraints or decisions that aren’t obvious from the code?
Sometimes a written explanation isn’t enough, and we really want to walk a reviewer through the change. Show them the difficult parts, explain the alternatives you considered, and answer questions while you’re both looking at the code. Go synchronous. A short conversation can be more effective than exchanging comments over several hours, particularly when the reviewer needs context the diff doesn’t provide. We don’t need to turn every pull request into a meeting, either. We’re trying to make review easier, not fill everyone’s calendar.
Give names to your claims
A descriptive name gives a reviewer a claim to examine.
Consider a function named is_authorized. That’s a useful name because it tells us what function the function performs. But does it actually check authorization, or merely whether someone is logged in? The name communicates intent. The reviewer will use the implementation to determine if that claim holds.
Functions with one clear purpose help in the same way. We can examine what a function promises without having to understand several unrelated operations alongside it. Breaking a function into smaller pieces helps when the new boundaries make those promises clearer. More functions aren’t automatically better.
Conventions are useful, too. An established pattern tells reviewers where to look for input validation, error handling, and changes to state. When code follows those conventions, reviewers can spend less time finding their way around. When it departs from them, the difference is easier to notice.
Comments can preserve information that names and structure cannot: an external constraint, an unexpected behavior, or why an apparently simpler solution won’t work. A comment that merely describes the next line of code doesn’t tell the reviewer much. One that explains why the obvious implementation would be wrong might save everyone considerable trouble.
Answer questions before they’re asked
Tests make pull requests easier to review when they show the behavior being changed. An acceptance test can show what a user is expected to be able to do. Tests for error conditions and edge cases can show what should happen when things don’t go according to plan.
But tests aren’t certificates of correctness. A passing test can check the wrong expectation. Coverage can tell us which code ran without telling us whether the tests checked what matters. That’s part of the reviewer’s job: examine the claims made by the tests, not just whether they passed.
What behavior changed? What happens when an input is missing or invalid? What happens when a dependency fails? Does the code do only what it’s authorized to do? Are we testing the intended behavior, or merely confirming what the implementation already does? Different changes deserve different questions. A change to a security boundary needs scrutiny that a renamed variable probably doesn’t. A new database operation raises questions about data integrity. A change to a busy service may need attention to performance, instrumentation, and behavior under load.
We don’t need to ask every question of every pull request. We need to understand enough about the change to know which questions matter.
The next review
A review isn’t finished when the reviewer leaves a comment. The author still has to consider the feedback, address the problems it reveals, and ask questions when a concern isn’t clear. Reviewers have a responsibility here, too. An actionable comment should explain the concern well enough that the author can investigate it. It doesn’t always need to prescribe the solution.
Sometimes the most useful review comment is a question that exposes an assumption neither person had noticed. We can all learn from the process. When the same questions come up in review after review, perhaps our code, conventions, tests, or pull-request descriptions aren’t communicating something they should.
And reviewers remember. If your pull requests consistently make the work understandable, people learn what to expect. You may find it easier to get reviews, and your reviewers can spend more of their attention examining the change rather than figuring out what they’re looking at. That helps the next review, and the one after that. It also helps future you, who will eventually have to understand and maintain the code.
It’s easier to question a decision while a change is still under review than to discover its consequences in production. Good reviews are a pound of prevention. Cures aren’t sold anymore by the ounce.
A code review cannot establish the quality of an entire system. But it can help us understand a change, examine evidence that it works, and find problems before they become production problems.
We started by interrupting another person’s work. A good pull request and a thoughtful review can make that interruption worthwhile.
If all else fails, use dark mode. Light attracts bugs.