Back to Blogs
November 5, 20255 min read

Code Reviews That Actually Help

Code review is one of the highest-leverage activities in a software team, and most teams do it badly. Here's how to make reviews genuinely useful.

The Purpose of Code Review

Most teams think of code review as a quality gate: catch bugs before they merge. That's a valid goal, but it's the least interesting one.

The more valuable goals of code review are:

  • Knowledge sharing — every reviewer learns how the author approached the problem, every author gets a second perspective on their decisions
  • Maintaining consistency — a second pair of eyes catches deviations from conventions that the author might not notice
  • Raising the team floor — junior engineers learn from senior feedback; senior engineers stay connected to what junior engineers are working on and struggling with

When review is only a gate, it becomes adversarial. When it's a collaboration, it makes everyone faster.

What to Look For (and What Not To)

Most review comments fall into two categories: style and substance. Style is formatting, naming, indentation. Substance is correctness, architecture, edge cases, and performance.

Automate style. If your team is arguing about whether there should be a space inside object braces, you're wasting review time. Configure Prettier, ESLint, or gofmt and enforce it in CI. When a linter or formatter can catch it, it shouldn't be a human's job.

Focus review on substance:

  • Does this code do what it's supposed to do?
  • Are there edge cases the author hasn't handled?
  • Is the abstraction at the right level?
  • Will this be easy to change in six months?
  • Are there security implications?
  • Does this introduce technical debt that should be called out?

Writing Better Review Comments

The way you phrase a comment determines whether the author responds with openness or defensiveness.

# Directive — sounds like criticism, shuts down discussion
Bad: "Don't do it this way."

# Exploratory — invites discussion
Good: "I wonder if we could use X here instead — it might simplify the error handling. Thoughts?"

# Directive without context — unhelpful
Bad: "This will cause issues."

# Specific with reasoning — actionable
Good: "This could cause a race condition if two requests arrive simultaneously.
Consider adding a database-level constraint here, or wrapping this in a transaction."

Label your comments:

  • Nit: minor stylistic preference, not worth holding up the PR
  • Suggestion: I think this could be improved, but it's your call
  • Question: I'm not sure I understand this — help me see what I'm missing
  • Blocker: this needs to change before merge

These labels set expectations. The author knows not to hold up the PR for a nit but should address a blocker before merging.

How to Receive Review Feedback

Good review recipients separate the feedback from the messenger. A comment on your code is not a comment on you.

When you get feedback that you disagree with:

  1. Assume positive intent — the reviewer is trying to make the code better
  2. Ask for more context if you don't understand the concern
  3. If you still disagree, explain your reasoning and ask for the reviewer's response
  4. If you're at an impasse, involve a third person rather than blocking the PR

When you get feedback that's vague:

  • "This is confusing" → ask "What specifically is confusing?"
  • "This could be better" → ask "What would you change?"

Vague feedback is the reviewer's responsibility to fix, but getting clarity is everyone's interest.

The LGTM Trap

"LGTM" (Looks Good To Me) as the only review comment is a failure mode. It means the reviewer either didn't read carefully, didn't understand the code, or was too uncomfortable to raise issues.

The antidote is to write at least one substantive comment on every PR you review. Even if the code is excellent, there's almost always something to observe — a question about the design decision, a note about what you learned from the approach, a minor suggestion. This signals that you actually read the PR and that the author can expect substantive engagement.

Small PRs Are Better PRs

The single biggest factor in review quality is PR size. A 50-line PR gets a thorough review. A 500-line PR gets a skim and an LGTM.

This isn't laziness — it's cognitive load. Holding 500 lines of changes in working memory while thinking about correctness, edge cases, and architecture is genuinely hard. Reviewers reviewing large PRs frequently miss things.

As an author:

  • Break features into multiple PRs where possible
  • Separate refactoring from feature work into different PRs
  • Use stacked PRs (each depending on the previous) for sequential changes

As a reviewer:

  • Set a size limit and push back on large PRs. "This is too large to review effectively — can we split this?"

The best teams I've worked with had an unwritten rule: if a PR takes more than 30 minutes to review, it should have been two PRs.

Timing

Don't let PRs sit for more than one working day. A PR that waits three days for review blocks the author, forces context-switching when review finally happens, and makes the eventual merge more likely to conflict with other in-progress work.

If you're the reviewer and you're genuinely too busy, say so and set an expectation: "I'll get to this by tomorrow afternoon." That's better than silence.

The Culture Layer

Everything above is tactical. The deeper issue is that code review quality reflects team culture. In teams with psychological safety, engineers write honest reviews and receive them well. In teams where reviews are used to demonstrate knowledge or establish hierarchy, they become exercises in dominance that destroy motivation.

The best culture I've seen treats code review as a team sport: we're all trying to make the codebase better, the review is a conversation, and the goal is a good outcome for the product — not being right.

Written by

Zikri Akmal Santoso

Software Engineer

More Articles