Bain Measured It: AI Wrote 21% More Code and Review Ate 91% More Time
💡 Tool Tip:AI Code Reviewer, Code Complexity Analyzer, Unit Test Generator, Text Diff
There is a set of numbers in Bain's 2026 Global Technology Report that I would put on the wall before any model benchmark. Their April 2026 survey of 293 senior technology leaders found developers complete roughly 21% more tasks, while time spent reviewing the output rises about 91%, and each developer manages 47% more concurrent workstreams. The same respondents expect release cycles to be 148% faster and developer productivity 95% higher within one to two years, against the 20% to 27% they are capturing today. My first pass through this read as another "AI does not work" piece. The second pass showed something more useful: the constraint moved, and the budget attached to the constraint did not.
Self-reported data from 293 technology leaders: +21% tasks, +91% review time.
Where the numbers come from, and what they exclude
The source is the Bain Tech and Engineering Survey, April 2026, n=293. Four figures: +21% tasks, +91% review time, +47% concurrent workstreams, and expectations of +148% release-cycle speed with +95% productivity against 20-27% captured.
Be precise about the limits. These are self-reports from senior leaders, not instrumented telemetry. "Tasks completed" is a unit that conceals task size. And 21% and 91% are not the same unit, so they cannot be added.
Which means the conclusion everyone wants to write — AI makes you slower — is not what the report says. It says the constraint moved and its budget did not follow.
# The four numbers, and where they come from. Quote the sample size,
# because "Bain says" without n=293 is how a survey becomes folklore.
#
# source: Bain Tech and Engineering Survey, April 2026, n=293
# +21% tasks completed per developer
# +91% time spent reviewing output
# +47% concurrent workstreams each developer manages
# expected +148% release-cycle speed, +95% productivity (1-2 yrs)
# captured today: +20% to +27%
#
# What the numbers do NOT say, and this matters:
# - they are self-reported by senior leaders, not instrumented
# - "tasks completed" is a unit that hides task size
# - 21% and 91% are not in the same unit, so they cannot be added
#
# The temptation is to write "AI makes you slower". The report does not say
# that. It says the constraint moved, and the budget for the constraint did not.
python3 - <<'PY'
tasks, review = 1.21, 1.91
print(f"throughput multiplier : {tasks:.2f}x")
print(f"review load multiplier: {review:.2f}x")
print(f"review load per unit of output: {review/tasks:.2f}x")
# 1.91 / 1.21 = 1.58. For every unit of shipped output you now do 58% more
# review work than before. If review capacity did not grow, review is the queue.
PYReview is a queue, and queues have behaviour
Divide 91% by 21% and you get 1.58. For every unit of output, you now do 58% more review work. If review capacity did not grow, review is the queue.
Little's law makes it concrete. Forty changes a week at two review hours each with five reviewers: utilisation 0.80, backlog flat. Now multiply arrivals by 1.21 and per-item time by 1.58 and keep five reviewers: utilisation 1.91, with roughly 123 item-hours of new backlog per week.
A utilisation of 1.91 is not "busy". It is mathematically impossible to sustain, so the work queues, and the queue is where velocity goes to die. Notice the variable that did not change: reviewer count. That is the entire headline.
Two real levers and one fake. Real: reduce per-item review hours through smaller diffs, better tests and typed contracts. Real: raise capacity, with more reviewers or by moving review earlier. Fake: lower the bar, which only relocates the queue to production.
# Little's law, applied honestly. Review is a queue, and queues have behaviour.
# L = lambda * W queue length = arrival rate * time in system
#
# Before: 40 items/week arriving, 2.0 hours of review each, 5 reviewers at 40h.
# After: arrival rate rises with throughput, and per-item review time goes up
# because generated diffs are longer and less familiar to the reviewer.
python3 - <<'PY'
def queue(arrivals_per_week, hours_per_item, reviewers, hours_per_reviewer=40.0):
capacity = reviewers * hours_per_reviewer # item-hours available
demand = arrivals_per_week * hours_per_item # item-hours requested
return {
"capacity_h": capacity,
"demand_h": demand,
"utilisation": round(demand / capacity, 2),
"backlog_growth_h_per_week": round(demand - capacity, 1),
}
before = queue(40, 2.0, 5)
after = queue(40 * 1.21, 2.0 * 1.58, 5)
for label, q in (("before", before), ("after", after)):
print(label, q)
# before: utilisation 0.80, backlog flat
# after : utilisation 1.91, backlog grows ~123 item-hours per week
#
# 1.91 utilisation is not "busy". It is mathematically impossible to sustain.
# The work does not disappear; it queues, and the queue is where velocity dies.
# Note what did not change: reviewer count. That is the whole headline.
PY
# Two legitimate levers, and one fake one:
# real: reduce hours_per_item (smaller diffs, better tests, typed contracts)
# real: raise capacity (more reviewers, or move review earlier)
# fake: lower the bar (this just moves the queue to production)Lever one: make engineering knowledge machine-readable
The report's first element sounds pedestrian. It is not. An agent's cost is dominated by how much context it has to infer, so every convention you leave undocumented is a convention it guesses wrong, and every wrong guess becomes a review comment.
The cheapest version lives in the repository: a contract file that both humans and agents load. Three sections are enough — how to build and verify, which invariants must not break, and where things live.
Add one review rule while you are there: diffs over 400 changed lines must be split. Review quality falls off a cliff on large diffs, so this single rule removes a large slice of the review tax.
Why this attacks the 91%: most of that time is not "the code is bad". It is "the code is unfamiliar". Documentation is cheaper than reviewer attention, and reviewer attention is the resource that ran out.
# Lever one from the report: make engineering knowledge machine-readable.
# The insight is unglamorous. An agent's cost is dominated by how much context
# it must infer. Every convention you leave undocumented is a convention the
# agent guesses wrong, and every wrong guess is a review comment.
# A repository-level contract file is the cheapest version of this. Not a wiki
# nobody reads: a file in the repo, versioned, that both humans and agents load.
mkdir -p .agents
cat > .agents/CONTRACT.md <<'MD'
# Repository contract
## Build and verify
- build: npm ci && npm run build
- test: npm test -- --runInBand
- lint: npm run lint
- A change is not done until all three pass locally. CI is not a linter.
## Invariants an agent must not break
- no new runtime dependency without an explicit approval step
- public API types live in `src/types/public.ts` only
- migrations are append-only; never edit an applied migration
- feature flags default to off and are removed within 30 days
## Where things live
- handlers: `src/api/handlers/` one file per route
- domain: `src/domain/` no imports from `src/api/`
- fixtures: `test/fixtures/` generated, do not hand-edit
## Review expectations
- diffs over 400 changed lines must be split
- every new branch needs a test that fails without the change
MD
# Why this reduces review time: it converts "why did you do it that way"
# into a rule the agent can read before writing. The 91% is mostly not
# "code is bad", it is "code is unfamiliar". Documentation is cheaper than
# reviewer attention, and reviewer attention is the thing that ran out.Utilisation moving from 0.80 to 1.91 is not busy. It is unsustainable.
Lever two: automate verification so humans review judgement
Three gates, cheapest first. Gate zero is purely mechanical: lint, typecheck, tests, no human minutes. Gate one inspects diff shape and rejects anything over 400 changed lines. Gate two demands behavioural evidence: for source changes, a test that fails without the change.
The goal is not to automate review away. It is to spend human attention only on what a machine cannot check — is this the right change. Gates zero and one remove something like half the review hours and none of the judgement.
Gate two deserves emphasis. A test that passes with your change proves very little. A test that fails without it is evidence. The difference is small on paper and enormous in practice, because it decides whether a reviewer is reading code or guessing.
# Lever two: automate quality verification, so a human reviews judgement
# instead of mechanics. Three gates, cheapest first.
cat > .agents/gates.sh <<'SH'
#!/usr/bin/env bash
# Gate 0 - mechanical, no human time, fails fast
set -euo pipefail
npm run lint
npx tsc --noEmit
npm test -- --runInBand --silent
# Gate 1 - diff shape, catches the review-time killer
CHANGED=$(git diff --numstat origin/main...HEAD | awk '{s+=$1+$2} END {print s+0}')
echo "changed lines: $CHANGED"
if [ "$CHANGED" -gt 400 ]; then
echo "REJECT: diff too large to review well. Split it." >&2
exit 1
fi
# Gate 2 - behavioural evidence, the only gate a human should read
if git diff --name-only origin/main...HEAD | grep -qE '^src/'; then
# A test that fails without the change is worth more than a passing suite.
git stash list >/dev/null
npm test -- --runInBand --coverage --silent > .agents/coverage.txt 2>&1 || {
echo "REJECT: tests fail with the change applied" >&2; exit 1; }
echo "coverage written to .agents/coverage.txt"
fi
SH
chmod +x .agents/gates.sh
# The point is not to automate review away. It is to spend human attention
# only on the part a machine cannot check: is this the right change?
# Gate 0 and 1 remove maybe half the review time and none of the judgement.Lever three: measure the delivery process as a product
This is the step most teams skip, and it is the only one that tells you whether the first two levers worked.
I track four numbers and nothing else: review hours per week, which is the constraint itself; median changed lines, which is the lever you control; rework rate, which says whether the speed is real; and lead time, which is what leadership asks about.
The read is mechanical. If merged count rises while weekly review hours flatten, the architecture changed. If review hours rise in step with merged count, you added volume and called it velocity.
A year from now the interesting question will not be which model you used. It will be whether your delivery process got faster without getting worse. The report is blunt here: the bottleneck moved from writing code to everything around it, and most organisations have not built the architecture for the "everything around it" part. Two things follow. First, the 148% expectation is not a model problem, so no model release closes it. Second, the teams that close it will look dull from the outside — smaller diffs, written invariants, automated verification, four numbers every week.
# Lever three, and the one most teams skip: treat the delivery process as a
# product with its own metrics. Without this you are guessing which of the
# two levers worked.
python3 - <<'PY'
import json, statistics
def weekly_metrics(rows):
lead = [r["lead_time_h"] for r in rows]
review = [r["review_h"] for r in rows]
size = [r["changed_lines"] for r in rows]
rework = sum(1 for r in rows if r["rework"]) / len(rows)
# Review load per merged change is the number that predicts the wall.
return {
"merged": len(rows),
"median_lead_time_h": statistics.median(lead),
"median_review_h": statistics.median(review),
"median_changed_lines": statistics.median(size),
"review_hours_per_week": round(sum(review), 1),
"rework_rate": round(rework, 2),
}
sample = [
{"lead_time_h": 31, "review_h": 3.2, "changed_lines": 210, "rework": False},
{"lead_time_h": 58, "review_h": 6.4, "changed_lines": 690, "rework": True},
{"lead_time_h": 22, "review_h": 1.8, "changed_lines": 120, "rework": False},
{"lead_time_h": 74, "review_h": 9.1, "changed_lines": 980, "rework": True},
]
print(json.dumps(weekly_metrics(sample), indent=2))
# Track four numbers weekly and nothing else:
# review hours per week <- the constraint
# median changed lines <- the lever you control
# rework rate <- whether speed is real
# lead time <- the outcome leadership asks about
#
# If review hours per week flattens while merged count rises, the architecture
# changed. If review hours rise in step with merged count, you only added volume.
PY
# A year from now the interesting question will not be which model you used.
# It will be whether your delivery process got faster without getting worse.
# The report's framing is blunt about this: the bottleneck moved from writing
# code to everything around it, and most organisations have not built the
# architecture for the "everything around it" part yet. Two things follow.
# First, the 148% expectation is not a model problem, so no model release
# closes it. Second, the teams that close it will look boring from outside:
# smaller diffs, documented invariants, automated verification, weekly numbers.The real levers: smaller diffs, written invariants, automated verification.
📌 Frequently Asked Questions
What is the source and sample size for these numbers?
The Bain Tech and Engineering Survey, April 2026, covering 293 senior technology leaders. The findings appear in "The Missing Architecture for Agentic Software Development", part of Bain's 7th annual Global Technology Report.
Can the 21% and 91% figures be compared directly?
They cannot be added, but they can be divided. 21% is the relative change in tasks completed and 91% is the relative change in review time, so they are different units. Dividing gives 1.58, meaning 58% more review work per unit of output, which is the ratio that identifies review as the constraint.
Why is review described as a queue?
Because it is completed by a fixed number of people with fixed hours while changes arrive at a rate. Little's law applies: when arrivals rise 21%, per-item time rises 58% and reviewer count is unchanged, utilisation goes from 0.80 to 1.91 and the backlog grows every week rather than occasionally being busy.
What three things does the report say close the gap?
Make engineering knowledge machine-readable so agents infer less; automate quality verification so humans review judgement rather than mechanics; and run the software delivery lifecycle as a continuously improved product with its own metrics.
Is 148% faster release cycles realistic?
The report presents it as respondents' one-to-two-year expectation against 20-27% captured today. It is not a forecast of model capability but an estimate of the ceiling if review, governance and delivery are rebuilt. Whether it is reachable depends on that rebuild, not on which model you pick.
🔧 Recommended Tools
AI Code Reviewer
Move mechanical checks off human time and keep judgement.
Code Complexity Analyzer
Find the changes that will always stretch review time.
Unit Test Generator
Get the failing-without-the-change test before review starts.
Text Diff
Inspect diff shape to decide whether it should be split.
AI ROI Calculator
Work out where the automated hours actually go.