Skip to main content
Best Practices

Why Your Code Review Should Start With Design, Not Bugs

Stop hunting for bugs first. The real value of code review is design feedback. Here's why starting with design makes your reviews faster, more effective, and less painful.

The Misconception: Code Review Is About Finding Bugs

We all think code review exists to catch bugs before they hit production. That's the mental model most of us carry, and it's wrong. At Google, where they've studied this at massive scale, the primary purpose of code review is not to find bugs at all. In a study of over nine million code changes (Sadowski et al., 2018), they found that the four key expectations of code review were education, maintaining norms, gatekeeping, and accident prevention. Catching bugs was not even in the top four. That's a profound insight, and it should reshape how you approach every single review you do.

When you start a review by scanning for bugs, you miss the forest for the trees. You're so focused on the syntax error in line 47 that you don't notice the design is fundamentally flawed. And even if you do catch the bug, you've spent your most valuable attention on something a linter or a unit test could have caught. The truth is, the highest-value feedback you can give is about design, not bugs.

The Question: Should You Review Design First or Bugs First?

So here's the question that drives everything I'm about to say: When you open a pull request, should you start by looking at the overall design, or should you dive into the implementation details and hunt for bugs? The answer, based on both Google's engineering practices and my own years of reviewing code, is unambiguous: design first, bugs second. Google's official code review guidelines explicitly state that the most important thing to cover in a review is the overall design of the change, before you even look at functionality, complexity, tests, naming, or comments (Google Engineering Practices - What to look for in a code review). That's not a suggestion—it's a directive.

I've been on both sides of this. As a reviewer, when I start with design, I catch architectural problems early—things like a module that's doing too much, a dependency that's being introduced unnecessarily, or a change that violates the existing patterns of the codebase. As an author, when a reviewer starts with design, I get feedback that actually improves my code, not just a list of typos. The bug-hunting approach feels productive because you're finding concrete issues, but it's the design feedback that moves the needle on code health.

Why Design-First Reviews Are Faster and More Thorough

You might think that starting with design slows you down, but it actually speeds things up. Google's data shows that small changes are reviewed more quickly and more thoroughly, and that's directly tied to how you focus your attention (Google Engineering Practices - Small CLs). When you start with design, you're naturally forced to understand the change at a high level before you dive into the weeds. That understanding makes you a better bug hunter, too—you know what the code is supposed to do, so you can spot when it's not doing it.

But there's a deeper reason design-first is faster: it prevents the worst kind of review—the one where you approve a change because the code is 'fine' on a line-by-line basis, but the overall design is wrong. That's the review that comes back to haunt you six months later when you have to refactor the whole thing. Design-first reviews catch these problems early, when they're cheap to fix. And let's be honest, a review that catches a design flaw is worth ten reviews that catch a missing semicolon.

The speed argument also applies to the author. When you give design feedback first, the author knows immediately if they need to rework the entire approach or just tweak a few details. If you bury design feedback in a list of nits, the author might address the nits and resubmit, only to have you say 'actually, the design is wrong'—and then they have to redo everything. That's a waste of everyone's time.

How to Actually Do a Design-First Review (With a Comparison Table)

So how do you structure a design-first review? It's not just a matter of reading the diff from top to bottom. You need a deliberate process. Here's what I've found works, and I'll compare it to the bug-first approach:

Review StepDesign-First (Recommended)Bug-First (Common Mistake)
StartRead the PR description and understand the intended behavior change.Jump straight into the diff, looking for syntax errors.
FocusEvaluate the overall architecture: does this fit the codebase? Is the approach sound?Hunt for input validation gaps and SQL injection.
Time SpentMajority of time on design, then check functionality and tests.Majority of time on implementation details, then maybe glance at design.
Feedback StyleComments about structure, patterns, and maintainability.Comments about specific lines, often nitpicking.
ResultAuthor knows if the approach is valid before polishing.Author polishes, then gets told the approach is wrong.

This table captures the essence. Design-first isn't about ignoring bugs—it's about sequence. You start with design, then you look for bugs, but you never let bug-hunting take precedence over design. A concrete example: in a recent review of a Django view that handled file uploads, I started by looking at the overall flow. I noticed the view was doing too much—parsing the file, validating it, storing it, and logging—all in one function. That's a design problem. If I had started with bugs, I might have caught a path traversal issue (which is real, and important), but I would have missed the bigger issue that the function should be split into smaller, testable pieces. And fixing the path traversal is easy once the design is clean.

The Standard: Approve When It Improves Code Health

Now, what does 'good enough' mean? Google's senior review principle is that you should approve a change once it definitely improves the overall code health of the system, even if it's not perfect. They say 'there is no such thing as perfect code, there is only better code' (Google Engineering Practices - Standard of Code Review). That's a liberating standard, and it directly supports design-first. If the design is sound and the change improves the codebase, you can approve it even if there are a few nits left. You don't need to block on a missing comment or a slightly awkward name.

This is where 'LGTM with comments' comes in. Google explicitly encourages reviewers to give an LGTM (approval) while leaving unresolved comments when they're confident the developer will address them, or when the comments are minor—like sorting imports or fixing a typo (Google Engineering Practices - Speed of Code Reviews). I've adopted this in my own reviews, and it's transformed my workflow. Instead of holding a PR hostage over a nit, I approve it and list the nits. The author knows they're not blocking, and the review is faster for everyone. But—and this is key—I only do this when the design is solid. If the design is flawed, I request changes without hesitation.

Let me give you a concrete example from my experience. A developer on my team submitted a PR that refactored a utility function into a new module. The code was well-written, tests passed, and there were only a few minor style issues. But the design was wrong: the new module was tightly coupled to a specific database driver, making it impossible to reuse elsewhere. That's a design flaw that would cause pain later. I requested changes, even though the code was 'working'. The author reworked it to use a generic interface, and the result was far more maintainable. That's the difference design-first makes.

The Most Important Thing to Remember

So here's the single most important thing to remember: Start your review with design, not bugs. It sounds counterintuitive, but it's the fastest path to better code health. When you open a PR, first ask 'Is this the right way to solve the problem?' before you ask 'Is there a bug in line 47?' You'll find that your reviews become more valuable, your team's code improves faster, and you'll actually enjoy the process more. And if you're an author, when you receive a review that starts with design feedback, thank the reviewer—they're giving you the feedback that matters.

Now, I'm not saying bugs don't matter. They do. But they're not the primary focus. Google's own data shows that at Google, only a small fraction of reviews actually find bugs—the median change is just 24 lines, and over 80% of reviews finish in a single round of comments (Sadowski et al., 2018). That's because the real value of review is in the conversation about design, not in the bug hunt. So next time you're about to comment on a missing semicolon, stop. Look at the design first. Your team will thank you.

Sources

  • Google Engineering Practices - What to look for in a code review - https://google.github.io/eng-practices/review/reviewer/looking-for.html
  • Google Engineering Practices - Standard of Code Review - https://google.github.io/eng-practices/review/reviewer/standard.html
  • Google Engineering Practices - Speed of Code Reviews - https://google.github.io/eng-practices/review/reviewer/speed.html
  • Modern Code Review: A Case Study at Google (ICSE-SEIP '18) - https://www.papercache.org/papers/mlsys/system/2026/03/25/modern-code-review-a-case-study-at-google

Share this article:

Comments (0)

No comments yet. Be the first to comment!