DEV Community

Cover image for I Stopped Reviewing Code Line by Line. Here's What I Review Instead.
Anas Issath
Anas Issath

Posted on Originally published at Medium

I Stopped Reviewing Code Line by Line. Here's What I Review Instead.

When AI writes half the diff, reading every line is no longer the job. Knowing where to look is.

Review Risk, Not Lines

Last quarter, I counted.

On an average day, I was asked to review somewhere between 1,500 and 2,500 lines of code across our team's pull requests. A year earlier, that number was closer to 600.

The team hadn't doubled. The output had.

AI assistants had made everyone faster at producing code. Nobody had made me faster at reading it.

So I did what most leads do. I skimmed. I looked for obvious mistakes, checked that the tests passed, left a couple of comments about naming, and clicked Approve.

Then a bug reached production that had been sitting in a PR I approved. It wasn't hidden in clever code. It was hidden in a perfectly clean, well-formatted, 300-line diff that I had read from top to bottom and still missed.

That was when I accepted something uncomfortable:

Line-by-line review doesn't scale anymore. And pretending it does is worse than admitting it doesn't.


Why Line-by-Line Review Is Breaking

Code review was designed for a world where writing code was the slow part.

A developer spent a day on a feature. The reviewer spent thirty minutes reading it. The ratio worked.

That ratio is gone.

Today a developer can produce in an hour what used to take a day. The diff looks polished. The formatting is perfect. The variable names are sensible. It reads like good code, which is exactly the problem.

AI-generated code fails differently from human code:

  • Humans make messy mistakes. Typos, awkward logic, half-finished thoughts. They're easy to spot because they look wrong.
  • AI makes clean mistakes. A missing permission check. A query inside a loop. A transaction that doesn't cover the step it should. They look completely right.

When everything looks right, reading line by line turns into scanning for things that look wrong. And the dangerous bugs don't.


What I Review Instead

I didn't stop reviewing carefully. I changed where I spend the care.

Now, before I read a single line, I ask five questions. Each one points my attention at the place where real damage happens.

1. What changes about the data?

This is always my first stop.

Migrations, model changes, anything that writes to the database. Code can be rolled back in minutes. Data can't.

I look for:

  • Migrations that lock large tables
  • Fields renamed or removed while old code still depends on them
  • Writes that should be inside a transaction but aren't
  • Defaults that will quietly fill millions of rows

If the data layer is wrong, nothing else in the PR matters.

2. Who is allowed to do this?

The second most expensive bug is a permission bug.

For every new endpoint or view, I ask one question: "Can a user reach data that isn't theirs?"

I check that queries are scoped to the current user or organisation, not just filtered by an ID from the request. AI-generated views are very good at returning the right object. They're much less reliable at returning only the right object.

3. What happens at 100× the data?

A query that runs in 20 milliseconds on a developer's laptop can take 20 seconds in production.

I look for:

  • Queries inside loops (the classic N+1)
  • Missing select_related or prefetch_related
  • Filters on columns with no index
  • Anything that loads a whole table into memory

I don't need to read every line to find these. I need to find every place the code touches the database, and read those slowly.

4. What happens when it fails?

Happy paths are easy to review. Production lives in the unhappy ones.

  • What if the external API times out?
  • What if the Celery task runs twice?
  • What if the user double-clicks the button?

If the answer is "it probably won't happen," it will. Usually on a weekend.

5. Can the author explain it?

This last one isn't about the code at all.

For any non-trivial change, I ask the author to explain the approach in two or three sentences. Not to test them. To find out whether the design is theirs or just accepted.

If they can explain it, I trust the rest of the diff more. If they can't, that tells me where to slow down.

I no longer review code. I review risk. The code is just where the risk lives.


What I Let Go Of

Shifting focus means consciously caring less about some things.

I've mostly stopped commenting on:

  • Formatting and style. Linters and formatters do this better than me.
  • Naming preferences. Unless a name is actively misleading, it's not worth a review round.
  • "I would have done it differently." If it's correct, safe and readable, my preference doesn't matter.

This was hard at first. Style comments feel productive. They're visible and easy to write.

But every minute I spent on a variable name was a minute I didn't spend on a missing permission check.


How the Team Changed

The five questions didn't just change how I review. Over time, they changed how the team writes PRs.

When people know the reviewer will start with data, permissions, scale, failure and explanation, they start answering those questions before the review.

So we added a short section to our PR template:

## Risk notes
- Data changes:
- Permission impact:
- Performance concerns:
- Failure handling:
- Anything I'm unsure about:
Enter fullscreen mode Exit fullscreen mode

That last line turned out to be the most valuable. When someone writes "I'm not sure the retry logic is right," they've just told me exactly where to look.

Reviews got faster. And for the first time in a while, they got better at the same time.


The Real Job of a Reviewer

For a long time, I thought a good reviewer was someone who read everything and missed nothing.

That was never realistic. With AI in the loop, it's not even possible.

A good reviewer today is someone who knows where the bodies are usually buried: the data layer, the permission boundary, the query that scales badly, the failure nobody planned for. They spend their attention there, and let tools handle the rest.

AI made writing code cheap. It made judgment more expensive. Review is where that judgment gets spent.


Over to You

How do you review code now that so much of it is AI-generated? Do you still read every line, or have you changed your approach? I'd like to know what's working for other teams. Tell me in the comments 👇

If this was useful, follow me here for more stories from the backend trenches, and subscribe to The Backend Tech Lead on Substack for weekly blueprints.

Top comments (0)