17 February 20267 min read
In a distributed engagement, code review is not a quality gate that happens after management. It is the management. It is where standards are communicated, where misunderstandings surface while they are still cheap, and where you find out whether the person you hired can actually do the work.
Which is why it is worth treating as a designed process rather than something that happens when people get around to it. Most of the friction that gets described as "the outsourced team is slow" turns out, on inspection, to be a queue that the client's own engineers are not clearing.
The queue is the problem, not the reviewer
Work sitting in review is work that is finished and delivering nothing. Worse, the author has moved on to something else, so when the review eventually arrives they have to reload the entire context. A change reviewed within a few hours costs the author five minutes to address. The same change reviewed four days later costs an hour, and the second change stacked on top of it now needs rebasing.
Measure the wait, not the number of comments. If you track one thing about review, track how long a pull request sits before a human looks at it. That number is the honest measure of how well the engagement is being managed, and it is almost always the client side that makes it bad.
This is where the shared working day earns its keep. When your reviewers and the author are awake at the same time for most of the day, a same-day review is an ordinary expectation rather than an ambition. Across a gap of eight or nine hours it is structurally impossible, and everything above compounds.
Small pull requests are a management tool
A four hundred line change gets a review that says "looks good". A forty line change gets a review that finds the bug. This is not about diligence; it is about what a human can hold in their head.
With someone new, or someone remote, or both, small changes do something else as well: they shorten the feedback loop on direction. If the approach is wrong, you find out after half a day rather than after a week of work that now has to be discarded, along with the goodwill of whoever wrote it.
The practical instruction is to agree an upper bound and treat exceeding it as something that needs a reason. Generated code, mechanical renames and dependency bumps are the obvious exceptions and should be in their own changes anyway, precisely so they do not hide a real edit.
What to comment on, and what to leave alone
The most damaging review pattern with a new external contributor is the one where every comment carries the same weight. Twenty remarks arrive, three of them are correctness problems and seventeen are preferences, and the author cannot tell which is which. They fix all twenty, learn nothing about your priorities, and slow down.
Label the difference explicitly. A blocking comment says what is wrong and why it matters. A preference says it is a preference and can be ignored. Teams that adopt this convention find their review conversations get shorter within a fortnight.
- Blocking: it is incorrect, it is unsafe, it breaks an interface someone depends on, or it violates the definition of done.
- Worth discussing: the approach works but there is a reason to prefer another, and the reason is explained rather than asserted.
- Preference: naming, ordering, structure you happen to like. Say so, and let the author decline.
- Not review at all: anything a formatter or a linter can decide. If it is in a review comment, your tooling is missing.
Review in both directions
An arrangement where the client's engineers review the outsourced team's work and never the reverse creates a hierarchy nobody agreed to. It also wastes the most useful perspective available to you: someone who has seen other systems and has not yet learned to accept yours.
Have external contributors review internal changes too, at least in the areas they work in. It surfaces the assumptions your team stopped noticing, it makes the standard mutual rather than imposed, and it is the fastest way to find out how well someone actually understands the system, which is a much better signal than any interview.
Automate everything that is not judgement
Formatting, import order, lint rules, type checking, test runs, coverage thresholds if you use them: all of this should fail in CI, not in a comment written by a person at eleven at night. Every one of these that a human raises is a small tax on the relationship, and it is a tax paid disproportionately by the newest person.
The gain is not only speed. It is that once the mechanical objections are gone, the remaining comments are all substance, and a review full of substance reads as engagement rather than as gatekeeping.
When review becomes a bottleneck you built
Two symptoms to watch for. The first is a single reviewer through whom everything passes, usually the person who knows the system best and has the least free time. That arrangement feels safe and is a single point of failure that gets worse as the engagement grows.
The second is silent approval. Reviews that arrive within minutes with no comments, consistently, are not a sign of excellent code. They are a sign that someone has stopped reading, usually because the queue got long enough that clearing it became the goal. That is the point at which review has stopped being management and started being paperwork, and the defects it was catching are now reaching production instead.
Both are fixed the same way: more than one person capable of reviewing each area, and a queue short enough that reading properly is possible. If you cannot manage the second, you have taken on more delivery than you have capacity to direct, which is a scaling problem rather than a review problem.
