Issue #3: Code Reviews? You Don't Have Time For That!

pocketDevOps Newsletter

Welcome to the "pocket DevOps" newsletter.

This is a copy of the newsletter sent to subscribers' inboxes on May 31, 2026.

Not subscribed yet? Want the next issue delivered straight to your inbox? Join the newsletter here.

Code reviews don't have to be a burden. With the right setup, they become one of the most valuable tools in your team's workflow.

Are Code Reviews Actually Worth It?

Let's start with the obvious question: why bother? Are code reviews actually worth it? Or are they just another process that slows small teams down?

Anton Zaides looked at this question directly. His research answers three key questions:

  • Are teams without code reviews actually faster?
  • Are code reviews reducing bugs?
  • Does the quality of code reviews matter?

Read the article and draw your own conclusions. But my take: code reviews deliver value well beyond catching defects. They are one of the best knowledge-sharing mechanisms available. In a small team, that matters even more. If only one person understands a piece of code, you have a problem.

So yes, code reviews are worth it. But your time is precious. Let's talk about how to do them without letting them become a bottleneck.

Don't Waste Your Colleague's Time

Before you request a review, make sure you're actually ready. Your teammates will love you for this. Nothing kills motivation to review faster than looking at code that wasn't ready to be reviewed in the first place.

Is This Change Even Necessary?

Think twice before requesting a review. Do you actually want to ship this code? What are the consequences of merging it? Is this the right solution to the right problem? It's easy to get deep into implementation and forget to zoom out. A few minutes of honest reflection before requesting a review can save hours of pointless back-and-forth.

There's another angle here too. Research on code review psychology shows that even experienced developers tend to accept suggestions during review rather than defending their own reasoning - even when their original approach was better. If you're not confident the code is worth shipping, don't submit it for review just yet.

Let the Computer Do the Boring Work

Don't waste a colleague's time on things a tool can catch. Use static analysis and style checkers. The computer will do it faster and more reliably than any experienced developer. Tools don't get tired. They don't miss things because they've reviewed too many PRs today.

Run as many code analyzers as you can. Seriously. Different tools catch different problems, and there's surprisingly little overlap between them. If you want to see what taking static analysis seriously actually looks like, read about how NASA approached it for the Mars rovers.

Zero Compilation Warnings

Every compiler warning is a potential bug. The compiler is trying to tell you something. Listen to it. Treat warnings as errors. All of them, no exceptions.

Use multiple compilers if you can, because each one has a different perspective and catches things the others miss.

And don't stop at the default settings. Compilers ship with most warnings disabled out of the box. You have to opt in. Take the time to understand and enable additional flags. For GCC, I recommend starting with -Wall -Wextra -Werror -Wshadow -Wdouble-promotion -pedantic -fanalyzer. Your code should compile cleanly with all of them.

Run Your Tests First

Run all tests before requesting a review. All of them. Unit tests, integration tests, anything you have.

Your tests must prove two things: that the code works as intended, and that it meets the requirements. A reviewer should be able to look at your test results and know exactly what was verified and what wasn't. Don't make them guess.

Think of tests as executable documentation. They don't just verify the code - they describe what the code is supposed to do. Well-written tests tell the story of your feature better than any comment ever could.

If you can't prove your code works, it's not ready for review.

Ask AI

Yes, really.

Ask an AI assistant what it thinks about your code before sending it to a human. I know - AI can hallucinate and suggest nonsense. But even a wrong suggestion can be useful. Sometimes an odd comment makes you pause and reconsider something you glossed over, and you end up improving the code yourself.

Think of it as a rubber duck with opinions.

If you want to get more consistent results, write a set of review prompts tailored to your codebase - things the AI should always check. Chris Mason did exactly this for Linux kernel development. The prompts themselves won't apply to your firmware project, but the idea is worth stealing.

Automate the Whole Thing

Do all those steps above sound like a lot of extra work you didn't plan for? Yes. That's exactly why you shouldn't do any of it manually.

At the start of a project, invest time in setting up a CI/CD pipeline that runs all of this automatically - static analysis, style checks, compilation with strict flags, all your tests. Every time you push your code to your development branch.

Then the rule becomes simple: ask your colleague to review only when the pipeline is green. No green pipeline, no review request. This keeps quality consistent and stops reviewers from wasting time on issues the tooling should have caught.

Describe What Your Code Does

Think about the last time you reviewed someone else's code. How much time did you spend trying to figure out what the code was supposed to do? Probably more than the time you spent actually looking for bugs.

That's a problem. A reviewer should be able to focus on whether the code does the right thing, not spend their time trying to figure out what the code is doing in the first place.

Write clear comments. Write good commit messages. If a reviewer has to guess your intent, you've already failed the review.

Keep Your Changes Small

The smaller the change, the more thorough the review. Large pull requests get rubber-stamped - not because reviewers are lazy, but because the human brain can only hold so much context at once. Past a certain size, the review becomes a formality. Small, focused changes get properly examined.

Use atomic commits. Each commit should represent one logical change - a refactor, a bug fix, a new feature. Not all three at once. This makes it easier to understand the history, easier to revert if something goes wrong, and easier to review in the first place.

If you find yourself regularly submitting large PRs, look into stacked diffs. It's a technique for breaking work into a series of small, reviewable pieces without blocking your own progress. Gergely Orosz has a good write-up on the concept. And if you want to go smaller still, Tim Ottinger makes a compelling case for micro-commits.

Consider Pair Programming

Asynchronous code reviews have a built-in problem: waiting. You finish your code, open a pull request, and then - you wait. Your colleague is busy. They'll get to it. Maybe today, maybe tomorrow. In the meantime, you context-switch to something else. When the feedback finally arrives, you have to context-switch back. Every round of review and fixes adds another cycle of waiting.

There's a worse problem than the delay, though. The review happens after the work is done. If there's a fundamental problem with the approach - a wrong assumption, a misunderstood requirement, a design that won't scale - you find out only after you've spent days going in the wrong direction. All that work, and you have to redo it.

Pair programming sidesteps both of these entirely. Yes, it looks wasteful on paper. Two engineers, one keyboard, one task. Surely it would be faster to split up and work in parallel? Not necessarily. When two people work together in real time, problems surface immediately. There's no wrong-direction trap - someone spots the issue before you've gone too far. There's no waiting - review happens continuously, as part of the work itself. The knowledge is shared from the start, so you don't end up with code only one person understands. And the quality of decisions tends to be higher when two minds are working through the problem together.

It's not the right fit for every task. But when the work is complex, ambiguous, or risky - that's exactly when the cost of getting it wrong is highest. That's when pairing pays off.

Document Your Review Process

Without clear expectations, every review is a different game. What are we actually looking for here? Should the reviewer check the tests, or just the logic? When two people have different answers to these questions, you get inconsistent reviews and pointless arguments.

The fix is simple: write it down. Create a checklist that defines what reviewers should focus on - and equally important, what they should NOT bother with because the pipeline already handles it. Put it somewhere visible. Make it part of your team's workflow.

When expectations are explicit, reviews get faster and more focused. Everyone knows the rules. There's less debate, less ambiguity, and more actual reviewing.

What Should a Reviewer Actually Focus On?

Let the tools handle the mechanical stuff. A human reviewer should focus on what automated tools can't catch:

  • Architecture and design decisions - does this design make sense? Will it scale? Will it create problems down the line?
  • Comments and documentation - are they accurate? Do they help, or do they mislead?
  • Tests - do they actually prove the code works correctly? Are the right things being tested?

That's where human judgment adds real value. Everything else is a job for your pipeline.

Code Ownership

Opinions about code quality are often subjective. Two experienced developers can look at the same code and reach completely different conclusions - and both can have valid arguments.

You need a tiebreaker.

Assign Code Owners for each part of the project - someone with enough seniority and authority to make the final call when there's a disagreement. They're responsible for the quality in their area, and when debate stalls, their decision is final.

This isn't about one person always being right. It's about making sure debates have a clear endpoint so your team doesn't waste time going in circles.


That's it for this newsletter. I'd love to hear what you think about it. Just hit reply and tell me.

And see you in the next one.

Jakub Zawadzki