Skip to content
Practitioner9 min readUpdated September 2026

Verification Is The New Bottleneck

When producing a change is cheap, the constraint becomes establishing that it is correct. What that means operationally for review capacity, test confidence, and the shift from writing code to specifying and checking it.

The constraint in your delivery system has moved, and it probably moved without anybody announcing it. For decades the scarce resource was people who could write correct code. Capacity planning, hiring, estimation and team design all encode that assumption. It is no longer the binding constraint in most estates that have adopted coding assistants seriously. The binding constraint is now the capacity to establish that a change is correct and safe to release.

This is not a soft observation about quality culture. It is a statement about where the queue is. You can find it in your own data in an afternoon: measure the age distribution of open pull requests, and measure how long a change waits between "author says it is ready" and "a human has formed a judgement about it". In organisations where generation has got cheap and nothing downstream has changed, that second number is now the largest single component of lead time.

What follows is what it means operationally. Verification is not one thing — it is a chain of review capacity, test confidence, environment availability and human judgement, and each link fails differently. The practical work is identifying which link is actually binding in your estate, rather than assuming it is the one you are most comfortable fixing.

Review capacity is a queue, and it obeys the usual laws

Treat code review as what it is: a service station with a finite service rate, fed by an arrival process you have just accelerated.

The service rate is bounded by the number of people who can competently review a given part of the system, multiplied by the hours they will actually spend on it, divided by the effort per review. None of those three terms improved when generation got cheaper. The middle one may have got worse, because the same senior engineers are now also being asked to evaluate tooling, set standards for assistant use, and review a larger volume of change from everyone else.

Meanwhile arrival rate went up. The queueing consequence is not a matter of opinion. As utilisation of the review stage approaches one, wait time rises non-linearly, exactly as described in why busy teams are slow teams. Reviewers are now the most heavily utilised resource in the system, which means they are also the most sensitive to any additional load.

There is a second-order effect that is worse than the delay. When reviewers are saturated, review quality degrades before review throughput does. A saturated reviewer approves rather than blocks, skims rather than reads, and trusts the tests rather than the diff. The queue does not visibly grow, because the pressure is released through reduced rigour instead. You get the appearance of a healthy system and a quietly rising change failure rate, which will be attributed to almost anything except reviewer load.

Three failure modes when review is the constraint

Reviewers become a named dependency. Work stops moving because a specific person is on leave. This is a symptom of knowledge concentration, and it gets sharply worse when volume rises, because the people who understand the system deeply are the same people the assistant is least able to substitute for.

Authors carry more work in progress. While change one waits for review, the author starts change two. Then three. Work in progress rises, context-switching cost rises, and the rework when review finally lands on change one is now entangled with two and three. WIP limits apply to this exactly as they apply to everything else, and they are more necessary than before, not less.

Batch size creeps back up. Counterintuitively, an expensive review stage pushes authors towards larger changes, because if each review costs a week of waiting, you would rather wait once for a big change than five times for small ones. This is the transaction cost logic operating inside the development loop, and it undoes the batch size discipline you may have spent years building.

Trusted and untrusted suites

The second link in the chain is automated testing, and here the distinction that matters is not coverage. It is trust.

A trusted suite is one where a green run genuinely changes your belief about whether the change is safe, and where a red run is treated as information rather than as an obstacle. An untrusted suite is one where people have learned, correctly, that the result carries little signal — because it is flaky, because it tests implementation rather than behaviour, because failures are routinely re-run until green, or because everybody knows which parts of the system it does not really cover.

The difference between the two is the difference between verification costing minutes and verification costing a senior engineer's afternoon.

PropertyTrusted suiteUntrusted suite
Green runReduces verification effort substantiallyReduces it not at all
Red runInvestigatedRe-run, then investigated if persistent
Effect on reviewReviewer checks intent and designReviewer must also check correctness manually
Effect on batch sizeSupports small, frequent changesPushes towards large, rare ones
Under high change volumeScalesBecomes the bottleneck immediately

This is not new; it is the argument already made in test strategy for teams that ship daily. What is new is the leverage. When production was expensive, an untrusted suite cost you some rework and some anxiety. When production is cheap, an untrusted suite is the thing capping your throughput, because it forces every single change through the most expensive verification path you have, which is a human reading it carefully.

Why an untrusted suite is now worse than none

This sounds like a rhetorical flourish. It is not, and the mechanism is specific.

A team with no automated tests knows it has no automated tests. Its verification process is explicit: someone reads the change, someone exercises it, and the cost is visible and budgeted. The team makes rational decisions about batch size and risk on the basis of a cost it can see.

A team with an untrusted suite has a verification process that claims to be automated. The organisation's policies, its definition of done, its release gates and its risk appetite are all calibrated against an assurance level that does not actually exist. Changes are approved on the strength of a green tick that means nothing. The cost has not been removed; it has been converted from a visible cost into an unquantified risk, and the organisation has stopped budgeting for it.

Now raise the change volume by a large factor. The team with no tests hits a wall immediately and visibly — it cannot review that much by hand, and it knows it. The team with the untrusted suite does not hit a wall. It ships, on a signal that carries no information, at a higher rate than before. The defects arrive later, in aggregate, attributed to the tooling.

The shift from writing to specifying and checking

The practical change in the engineering role is that the expensive, valuable, distinctively human work has moved to the two ends of the loop: saying precisely what should be true, and establishing that it is.

Specification becomes the scarce skill. The quality of what comes out is now largely determined by the precision of what went in — the invariants stated, the edge cases named, the non-functional constraints made explicit, the intent described rather than the implementation dictated. Vague requirements used to produce slow progress, which was a visible signal. Now they produce fast progress in an unexamined direction, which is not.

Checking becomes a first-class activity with its own budget. It needs time allocated in planning, it needs to be visible on the board as a state with its own queue, and it needs to be someone's explicit accountability rather than an unpriced obligation absorbed between other tasks.

Executable specifications pay back more than they used to. Property-based testing states invariants rather than examples, and invariants are exactly the thing that survives a rewritten implementation. Where behaviour is non-deterministic, the equivalent is an evaluation harness, which is the same idea applied to systems where you cannot assert exact equality.

Reading becomes a taught skill, not an assumed one. Most engineers were trained to write and picked up reviewing by osmosis. When most of what an engineer does is judge candidate changes, reviewing is the primary skill and deserves to be trained deliberately — the subject of code review when code is cheap.

Relieving the constraint

Theory of Constraints prescribes a sequence: identify the constraint, exploit it, subordinate everything else to it, then elevate it. Applied here, concretely.

Exploit it. Stop wasting reviewer time on things that do not need a human. Formatting, lint, style, obvious null handling and common security patterns should be caught automatically before a human sees the change. Every automated check you add is a direct increase in effective review capacity, which is the highest-leverage automation available to you right now.

Subordinate to it. Limit work in progress so that the arrival rate at review is matched to its service rate. Enforce change size limits, because review effort is super-linear in diff size. Prioritise review over starting new work — the rule that finishing beats starting applies with unusual force when the constraint is downstream of you.

Elevate it. Broaden the pool of competent reviewers through pairing and rotation. Invest in the test suite until a green run is genuinely load-bearing. Buy pipeline speed; it is usually cheap relative to engineer time and it directly reduces the constraint's cycle time.

What to do on Monday

Measure the queue before you argue about it. For the last thirty merged pull requests, record time from ready-for-review to first substantive review comment, and time from ready-for-review to merge. Look at the distribution rather than the mean, and specifically at the eighty-fifth percentile — that is the number you can promise against.

Then run the trust test on your suite, which takes an hour and settles the argument. Ask the team two questions. If the suite is green, would you release without further checking? And when a test fails, what is the first thing you do? If the answer to the first is no, or the answer to the second is "re-run it", your suite is not currently reducing verification cost and any plan predicated on it doing so is unfunded.

Pick whichever of those two is worse and give it a named owner, a specific target and four weeks. Not a quality initiative. One number, one person, one month.