In Part 1 of this series, we explored what makes a pull request review truly effective, not just as a code quality gate, but as a chance for shared learning and team alignment. A good review starts before the first line of code is read: understanding the problem being solved, confirming the PR is “ready” with tests and documentation, and focusing energy on meaningful feedback instead of trivial fixes. That foundation (mindset, preparation, and purpose) sets the stage for the next step: how to actually conduct a great review. Read Part 1 here if you haven’t already: A Guide to Effective PR Reviews - Part 1
So let’s dive a little further into this topic and start talking about how we can make the review experience as effective as possible for us and our team. Few people actually enjoy the process, so the less painful we can make it, the better. Additionally, we want to make sure that any feedback we provide is well received. If feedback gets ignored, the whole exercise becomes a waste of time; exactly what we want to avoid. In order to make sure this process is seamless and effective, we need to take extra caution to use a respectful tone, focus on outcomes, balance thoroughness vs pragmatism, and be open to different approaches than we expected. Let’s take a brief minute to look at each of these principles.
Use a Respectful Tone
I bring this up first because it’s, perhaps, the most important piece of all of this. We need to take extra care to be respectful in our review comments. Text leaves plenty of room for misinterpretation. Anything that can be construed as abrasive or aggressive will immediately put the author on the defensive, causing more friction in the process. A defensive person will be less open to change or discussion and will prefer to have the process over sooner rather than later. This doesn’t benefit anyone. It’s important that we approach every review with the assumption that the author knew exactly what they were doing and is a trusted and respected member of the team. Now, I know: we’ve all worked with people that maybe don’t fit those qualifications. It is important, however, that we tell ourselves they do for the purpose of the review. “It’s OK to leave a lot of comments if a PR truly needs work. Just make sure we’re coming from a place of respect so the discussion stays productive.”
A good practice is to avoid commands and instead question. Instead of “change this line,” we might use “do you think it would be better if…?” Keep feedback focused on actionable comments or questions. Avoid questioning the validity of a line of code without offering some reasoning for the question.
Some examples:
Bad: “This needs to be in a try/catch block.”
Better: “Should we provide some sort of error handling here in case the input is null?”
Bad: “?? What is this?”
Better: “I’m not sure I understand what’s going on here? what is this block of code doing?”
Lastly, PR comments don’t always have to be change requests. It’s OK to pat each other on the back once in a while. Leaving positive comments too can go a long way toward boosting morale and team spirit.
Focus on Outcomes
Once we’ve established a foundation of respect and positive intent, we can shift our attention to what really matters during a review: the outcomes we’re driving toward. Now that we know how we should communicate with each other, what should we be communicating about? When reviewing code, it’s important to focus on the outcome of the code being changed and avoid getting hung up on personal preferences. A PR is not the right place for language or framework evangelism. While having an opinionated stack or approach isn’t necessarily bad, the PR isn’t the right place for those discussions. We should focus on current existing standards, of course, and ensure they’re not broken, but letting personal bias inform how code “should” be written should be avoided at all costs.
Part of what makes a team valuable is that everyone approaches problems in slightly different ways. Trying to force everyone into the same box limits creativity and can negatively impact team health in a huge way.
Example:
# Calculate the average of positive numbers in a list
total = 0
count = 0
for num in numbers:
if num > 0:
total += num
count += 1
average = total / count if count > 0 else 0
print("Average:", average)
Good code review callouts:
- "Could we use a built-in function like
sum()
with a generator expression to make this more concise and readable?" - "Should we handle the case when the list is empty or all numbers are negative differently? Right now it returns 0 silently."
- "Is there a way to combine the total and count calculations into a single loop comprehension to be more fluent with modern Python idioms?"
Bad/unhelpful callouts:
- "I don’t like that the variable is named
total
; it should besum_of_positive_numbers
." - This is a personal preference and not critical. - "You should use a
while
loop instead of afor
loop here." - Style change that’s likely not part of your company’s standards, not important.
You’ll notice that the unhelpful callouts don’t add clarity, they just enforce a personal preference. While valid, if it doesn’t improve readability or performance, it doesn’t belong in the review. Those conversations can happen later when setting new standards, but shouldn’t block a merge.
Balance Thoroughness vs Pragmatism
With our focus centered on results rather than preferences, the next challenge is figuring out how deep to go; knowing when thoroughness helps and when it just slows everyone down. It’s easy to treat every PR like it’s mission-critical, but not every change deserves the same level of scrutiny. We have to find a balance between being thorough and being pragmatic. The goal isn’t perfection; it’s progress without compromising quality. We should know when to dig deep and when to move fast. For example, if we’re reviewing a new core service or a security-sensitive area, it makes sense to take extra time: test locally, pull down the branch, and really think through the edge cases. But if the PR is a small styling fix or a minor refactor, we shouldn’t block it for nitpicks or micro-optimizations that don’t materially change the outcome.
Think of it as “risk-based reviewing.” The higher the impact of potential failure, the deeper our review should go. For everything else, focus feedback on readability, maintainability, and consistency. The trick is to give each PR the attention it earns, not the level our inner perfectionist wants to give. This helps keep development velocity high and avoids review fatigue, which can quietly erode quality over time.
Be Open to Different Approaches
And even with the right level of scrutiny, we can’t forget that there’s rarely one perfect solution; staying open to different approaches is what turns a review into a learning moment instead of a debate. The last thing to touch on here is that this is a great opportunity to learn. We’ve all had to learn new things; nobody’s immune to that. And something that becomes clearer the further we go in our careers is this: classes only get us partway there. The real learning happens in collaboration. PR reviews are a fantastic opportunity to share ideas, see different approaches, and expand our collective understanding of the codebase. Comments like “This is not how I would approach this problem; it’s better to do it this way…” aren’t helpful. They create friction and put the author on the defensive. We need to recognize that our approach and the author’s approach can both be valid. As long as the author’s solution is efficient, testable, maintainable, and solves the problem at hand, we should celebrate the difference in perspective and use it as a learning opportunity.
Empathy isn’t something most engineers are naturally strong at, but the review process is a great place to practice it. We need to assume trust in the author. Trust that they’ve done their due diligence in testing and validating the PR. If that trust isn’t there, the problem is cultural, not procedural. When we do request changes, we should frame them as questions rather than commands. Engineers respond better to prompts like “Have we considered an approach like X instead?” than to “This is cleaner as X.” It gives the author room to explain their reasoning or adopt the suggestion organically.
Finally, we can’t lose the forest for the trees. We all want the best possible code, but sometimes “good enough” is the right call. Spending three days debating minor details doesn’t save time if the original solution already works well. We need to trust that our teammates are solving problems to the best of their ability, and that should be enough. If we approach reviews as opportunities to learn rather than dictate, we’ll end up growing stronger as a team and more consistent as engineers.
Closing Thoughts
The PR review process is, at its best, a collaborative dialogue; not a courtroom. When we approach it with empathy, respect, and curiosity, reviews stop being a chore and start becoming one of the most valuable learning moments in our week. In this second part, we’ve covered how to approach reviews with the right tone, focus on meaningful outcomes, balance our thoroughness with pragmatism, and stay open to new ideas.
In Part 3, we’ll dive into something every reviewer struggles with: knowing what’s worth reviewing and what isn’t. Not every comment improves the code, and not every issue is worth a conversation. We’ll explore how to identify high-impact feedback, when to step back, and how to make sure our reviews actually move the team forward.