Skip to content

Merged Is Not Reviewed

25 min read

Merged Is Not Reviewed

· 25 min read
An editorial illustration on warm cream paper in black ink line work: an ordinary magnifying reading lens on a weighted desk stand held low over a long fanfold computer printout that runs off both edges of the frame. Directly beneath the glass one narrow band of the printout is drawn in full crisp detail with line numbers and legible assembly instructions, while the printout continues far to the left and right as progressively fainter unexamined ruling. Thin leader lines label the crisp band READ, the faint expanse MERGED, and the lens stand ONE REVIEW. A small all-caps serif title reading MERGED IS NOT REVIEWED sits in the upper left, and one thin ink-blue line runs along the bottom margin above the caption ATTENTION IS PRICED PER PULL REQUEST.

In July 2026, three researchers at Microsoft published the cleanest evidence yet that command-line coding agents make engineers more productive. Studying tens of thousands of engineers through an early-2026 rollout of Claude Code and GitHub Copilot CLI, they found adopters merged roughly 24% more pull requests than they otherwise would have, and the lift held across a four-month window.

Then they wrote this, in the abstract, about their own headline metric:

We use merged pull requests as our proxy for output, acknowledging that a merged PR is not the same as the value it delivers.

The industry quoted the 24% and dropped the sentence. That is worth dwelling on, because merge is not an arbitrary proxy. Merge is the verification gate. It is the moment a human is supposed to have decided the change is correct. Counting merges to measure productivity assumes the gate still means what it used to mean.

So I measured the gate. Twelve thousand two hundred and ninety-one merged pull requests, five major open-source repositories, 2025 against 2026. The result is not that review collapsed. It is stranger and harder to see than that.

Evidence for everything below: merged PRs from astral-sh/ruff, prisma/prisma, tailwindlabs/tailwindcss, vitejs/vite and withastro/astro, created 2025-01-01 to 2026-08-22, bot authors excluded. n = 6,947 (2025) and 5,344 (2026). Figures are month-normalized because 2026 is a partial year. Method, scripts and every confound are at the bottom.

Key Takeaways

  • The code arriving for review rose 42% per month. Review discussion per 100 lines fell 36%, in the same direction in all five repos. Median PR size rose 28%.
  • Time-to-merge did not move (15.0 to 14.5 median hours). The queue never backed up, because review depth was the shock absorber. A backlog would have been visible; this was not.
  • The share of PRs merged with zero reviews rose from 9.6% to 15.0%.
  • Nobody decided to review less. Reviewers did 22% fewer reviews per PR while each PR carried 18% more code. The two compound arithmetically into the depth loss.
  • Mandating review does not fix it. The one repo where unreviewed merges collapsed (13.2% to 3.3%, a policy step change) posted the steepest depth loss of all five, 0.79 to 0.27 threads per 100 lines. Coverage and depth diverge, and coverage is what dashboards track.

Why did code generation stop being the bottleneck?

Because the supply side scaled and nothing else did.

The Microsoft study is the strongest single data point: +24% merged PRs per adopter across tens of thousands of engineers, sustained over four months, with the effect concentrated in engineers who used the tools five or more days a week rather than those who merely had access. That is a real, replicated, causally-argued throughput gain. The authors even ran a placebo test, pretending the rollout started earlier and finding no similar jump.

The paper frames the whole exercise as a cost question. Token spend at organisational scale runs into millions of dollars a year, so misreading impact makes a rollout expensive without changing velocity. That accounting is careful about what the harness costs and silent about what the review costs, which is the asymmetry this post is about. One side of the ledger has a per-token price and a dashboard. The other side is somebody’s afternoon.

Nothing in that rollout added reviewers. Nothing in any rollout does. Review capacity is set by headcount, attention and calendar, and none of those respond to a CLI install. When one side of a pipeline gets 24% faster and the other side is fixed, the constraint moves. This is the least surprising claim in the post.

What is surprising is where the pressure went. I expected a backlog. I have watched review queues grow at multiple client engagements this year, and the four symptoms are consistent enough to name: work piling up waiting on approval, approvals that happen without anyone reading, individual diffs too large to review at all, and teams that stop trusting agent output and re-derive it by hand. Those are real, and if you are living one of them you do not need data to believe it.

The open-source data shows something else, and the difference is instructive.

What does the merged-PR metric actually measure?

It measures gate-clearing events per unit time. That is all it has ever measured.

This is fine when the gate is reliable, which is why nobody worried about it before. For twenty years, “merged” was a decent shorthand for “reviewed and accepted”, because the cost of producing a change was high enough that the review step was rarely the binding constraint. The proxy held because the thing it proxied for was cheap relative to the work.

Invert that and the proxy inverts with it. If generation is cheap and review is expensive, then counting merges tells you how fast the expensive step is being cleared, and says nothing about how thoroughly. A team that halves its review standards will post a productivity gain on this metric. So will a team that doubles its reviewers. The metric cannot distinguish them, and every published figure on AI coding productivity that I am aware of uses it.

I have written before about the delivery metrics we inherited from a slower era. This is the sharpest case of it. The measurement was not wrong. Its load-bearing assumption quietly stopped holding.

Did the diffs get bigger?

Yes, in all five repositories, by 28% at the pooled median.

Median additions per PR, 2025 against 2026, five repositories

Median lines added per merged pull request, 2025 compared with 2026. ruff 64 to 67. astro 46 to 63. tailwindcss 35 to 58. prisma 37 to 102. vite 11 to 14. All five repositories moved in the same direction. Source: GitHub GraphQL, 12,291 merged PRs.

MEDIAN ADDITIONS PER PULL REQUEST2025 against 2026, five repositories, bots excluded0306090120lines added (median)prisma102ruff67astro63tailwindcss58vite1420252026Source: GitHub GraphQL, 12,291 merged PRs, 2025-01-01 to 2026-08-22

Pooled, the median PR went from 46 to 59 added lines and the 90th percentile from 446 to 484. Per repo the effect ranges from marginal to dramatic: ruff moved 64 to 67, which is nothing, while prisma moved 37 to 102, a 2.76x increase significant at p = 1.9e-10. Three of the five are individually significant; vite (11 to 14) is not, and ruff is not.

What makes this credible rather than anecdotal is that all five moved the same way. With five repositories a unanimous split is the strongest result a sign test can return, and it floors at p = 0.062. I am not going to dress that up as p < 0.05. Call it a consistent direction with three well-powered confirmations inside it.

This aligns with the only other large-scale measurement in the area. GitClear’s Maintainability Gap analysis of 623 million changes from 2023 to 2026 found refactoring collapse from 21% of changed lines in 2022 to 3.8%, duplicated blocks up 81%, within-commit copy/paste up 41%, error-masking constructs up 47%, and cross-file function calls down 35%. Bigger diffs made of more repetitive, less-connected code. That is the shape of change code review was never optimised for.

What happened to review depth?

It fell 36%, and this is the part nobody has published.

GitClear measured the code. DORA measured the outcomes. Microsoft measured the throughput. None of them measured the review, and GitClear’s report says so explicitly: it covers authorship patterns and structural maintainability, not review process. So here is the review side, using inline review threads per 100 added lines as the depth proxy.

Review discussion per 100 added lines, by quarter

Inline review threads per 100 added lines, pooled across five repositories. 2025-Q1 1.00, 2025-Q2 0.89, 2025-Q3 0.66, 2025-Q4 0.64, 2026-Q1 0.76, 2026-Q2 0.43, 2026-Q3 0.36. Source: GitHub GraphQL, 12,291 merged PRs.

REVIEW DISCUSSION PER 100 ADDED LINESInline review threads, pooled across five repositories1.00.750.500.2501.000.890.660.640.760.430.3625Q125Q225Q325Q426Q126Q226Q3Source: GitHub GraphQL, five repositories, bots excluded. 26Q3 is partial (through Aug 22)

One point per quarter, pooled: 1.00, 0.89, 0.66, 0.64, then 0.76, 0.43, 0.36. Not monotonic, and I have left the 2026-Q1 bump in rather than smoothing it. The era comparison is 0.77 against 0.50, a 36% fall, and again the direction held in all five repositories: 0.81x in ruff, 0.73x in prisma, 0.82x in tailwindcss, 0.75x in vite, 0.34x in astro. Only astro’s drop is individually significant, with a bootstrap 95% interval of [0.18, 0.63] that excludes 1. The other four are directionally consistent and individually underpowered. That is the honest summary.

One reading of this number I did not have when I first published it: review discussion is also the channel through which a codebase’s judgment reaches the people who do not have it yet, so a 36% fall is a 36% fall in the teaching surface as well as in the scrutiny.

Meanwhile the share of PRs merged with no review recorded at all went from 9.6% to 15.0%.

Here is the mechanism, and it is the reason I do not think this is a story about anyone getting lazy:

Per pull request20252026Change
Mean reviews3.512.73−22%
Mean inline threads2.021.52−25%
Mean lines added261308+18%

Slightly less review attention per pull request, meaningfully more code inside each one. Neither change is dramatic on its own. Multiplied together they produce a 36% loss of scrutiny per line, and no individual anywhere in the process made a decision that felt like reviewing less. Review effort is allocated per pull request, because a pull request is the unit that shows up in a queue and gets a button pressed. Grow the payload behind the button and depth per line falls as arithmetic.

Why didn’t the queue back up?

Because review depth absorbed the load, and that is the finding I would most want a delivery lead to sit with.

Review load against merge latency, by quarter

Thousands of added lines needing review per month, against median hours to merge, by quarter. Load: 127.9, 121.4, 151.2, 204.4, 151.2, 214.8, 320.3 thousand lines per month. Latency: 9.6, 15.9, 18.0, 14.8, 16.8, 14.0, 12.3 median hours. Load rose without a corresponding rise in latency.

REVIEW LOAD ROSE. MERGE LATENCY DID NOT.Bars: thousand lines needing review per month. Line: median hours to merge0100k200k300k12812115120415121532024h12h025Q125Q225Q325Q426Q126Q226Q3Median hours to merge stayed between 9.6 and 18.0 throughoutSource: GitHub GraphQL, five repositories. 26Q3 partial (through Aug 22)

Pooled median time-to-merge was 15.0 hours in 2025 and 14.5 hours in 2026. It went slightly down. Across the five repositories it moved in no consistent direction at all: down in three, up in two, sign test p = 1.000. Over the same period the monthly volume of code needing review rose 42% by era, and the last quarter in the series is the heaviest in the dataset.

A system under 42% more load with flat latency has found capacity somewhere. It did not come from more reviewers. It came out of depth.

This is why the effect is so easy to miss. Every instrument a delivery org actually watches would report this system as healthy or improving. Cycle time: flat. Throughput: up. Review coverage: up in most places. PR merge rate: up. There is no red number anywhere. The thing that changed is the amount of human attention per line of shipped code, and nobody has a dashboard for that because until recently it did not need one.

Set this beside the DORA findings and the shape gets familiar. The 2024 report put it plainly: “AI adoption significantly increases individual productivity, flow, and job satisfaction. However, it also negatively impacts software delivery stability and throughput.” The 2025 report reframed AI as an amplifier, with throughput improving and the negative relationship to delivery stability persisting. Thinning review is a plausible mechanism for a persistent stability penalty that coexists with throughput gains. I want to be careful here: my data cannot establish that link, only note that the mechanism is available and the timing fits.

The four client symptoms fit here too, and the apparent contradiction resolves cleanly. In a commercial team with fixed reviewer headcount and mandatory approval, the shortage surfaces as queue time, because the merge gate genuinely blocks. In open-source repositories where maintainers control merge directly, the same shortage surfaces as thinner reading, because the gate bends instead of blocking. Same constraint, different release valve. Which one you get is a property of your process, not of the underlying problem, and the OSS failure mode is the more dangerous of the two because it is silent.

Does mandating review fix it?

No. The repository that mandated it lost the most depth.

Share of PRs merged with zero reviews, 2025 against 2026

Percentage of merged pull requests with no review recorded. tailwindcss 2.0 to 28.4. ruff 10.9 to 19.2. vite 13.7 to 24.1. prisma 0.3 to 0.6. astro 13.2 to 3.3, the only decrease, coinciding with an apparent branch-protection change.

MERGED WITH ZERO REVIEWSShare of merged pull requests, 2025 to 202620252026tailwindcss 2.0%28.4%vite 13.7%24.1%ruff 10.9%19.2%astro 13.2%3.3%prisma 0.6%astro is the only decrease, and it posted the steepest depth loss of the fiveSource: GitHub GraphQL, 12,291 merged PRs

Four of five repositories saw unreviewed merges rise, two of them sharply: tailwindcss from 2.0% to 28.4% and vite from 13.7% to 24.1%, both with bootstrap intervals well clear of 1. astro went the other way, 13.2% to 3.3%, and the quarterly series makes the reason fairly clear. It steps from 18.9% in 2025-Q3 to 4.1% in 2025-Q4 and stays low. That is not a culture shift; that is a branch-protection rule landing.

So astro ran the experiment for us. Required review took coverage to roughly 97% of merged PRs. And astro posted the largest depth loss in the dataset, 0.79 to 0.27 threads per 100 lines, a 66% fall and the only one significant on its own.

Requiring a review produces a review. It does not produce reading. When every PR must carry an approval and the PRs are getting bigger, the approval is the thing that scales, because it is the thing being measured.

That is the practical warning in this whole exercise. Coverage is easy to mandate, easy to measure, and easy to satisfy. Depth is none of those. A policy that moves coverage to 97% while depth halves will look like a governance win on every report it appears in.

What should you instrument instead?

Four metrics, none of which require new tooling, all computable from the GitHub API today.

Review threads per 100 changed lines. The single most useful number in this post. It normalises review effort against the thing that grew. Track it per team per quarter. A falling line means your review process is being diluted even if every other indicator holds.

Share of merged PRs below a depth floor. Pick a floor (one inline thread per 200 changed lines is a defensible start) and track what fraction of merges fall under it. This catches the specific failure the pooled averages hide: a small number of thoroughly-reviewed PRs masking a large number of waved-through ones. In this dataset, 59.4% of 2026 merges carried no inline comment at all.

Review load per reviewer per week, in changed lines. Capacity planning needs a load figure, and PR counts are the wrong unit now that PR size is moving. If this number doubles, you have either doubled reviewers or halved attention, and you should know which.

Revert-or-fix within 14 days. The outcome check that closes the loop. Depth metrics are proxies; this one is a consequence. If thin review is costing you, it shows up here before it shows up in an incident.

None of this argues against agents, and none of it is solved by slowing down. It is solved by moving verification off the critical path of a human reading a large diff under time pressure. That means machine review taking the first pass at the diff so human attention lands on decisions rather than syntax; it means gating on the trajectory rather than the output so a passing test is not the whole story; and it means specifying intent tightly enough up front that review has something to check against, which is the argument for treating the failing test as the spec. It also means keeping diffs small on purpose, which is now a review-capacity decision rather than a style preference.

The four failure modes I have watched at clients this year are all downstream of the same shortage, and named failure modes are easier to instrument than a general sense that things feel worse.

What I threw out, and one thing I nearly got wrong

Two claims did not survive checking, and a third turned out to be real but routinely mangled. Saying so is more useful than quietly not citing them.

DORA’s widely-repeated “every 25% increase in AI adoption brings a 1.5% throughput decrease and a 7.2% stability decrease” does not appear on the 2024 report page, which states the relationship directionally without those figures. I used the directional quote instead.

The cluster asserting that AI-heavy teams merged 98% more PRs with PR size up 154%, review time up 91% and bugs up 9%, all as one coherent finding, circulates on several vendor blogs with no attribution. I nearly discarded it entirely. That would have been a mistake, because the individual numbers are real: they come from Faros telemetry covering more than 22,000 developers across 4,000-plus teams. What the vendor blogs did was splice two different reporting years into one sentence. Review time +91%, PR size +154% and PRs per developer +98% are the earlier figures. The later ones are review time +441%, PR size +51.3% and PRs per developer +16.2%. Quoting them as a single set is wrong even though each number is sourced.

The mangling matters more on one figure in particular. Faros reports that “31% more PRs are merging with no review at all.” That is a relative increase, not an absolute share, and it is very commonly restated as “31% of PRs merge with no review”, which is a different and much stronger claim. It is restated that way almost everywhere, including, until this post went up, in two earlier posts on this site, which I have since corrected. Reading a relative change as an absolute level is the single easiest way to overstate this whole problem, and the problem is serious enough without help.

Read correctly, it is a direct corroboration of my result on a completely different population. Faros measured commercial teams and found the number of unreviewed merges up 31%. I measured open-source repositories and found the share of unreviewed merges up 56% in relative terms, 9.6% to 15.0%. Two independent datasets, two different worlds of review culture, same direction and comparable magnitude. That is worth more than either number alone.

The absolute levels are the interesting difference. Commercial teams mostly cannot merge without an approval, so their shortfall has to surface somewhere other than a missing review: in queue time, or in the depth of the review that does happen. That is the astro pattern from earlier in this post, playing out across an industry rather than one repository.

If a number in this post matters to you, the scripts that produced it are reproducible against any repository you have read access to, and the confounds are below rather than in a footnote.

Methodology

Data. Merged pull requests from astral-sh/ruff, prisma/prisma, tailwindlabs/tailwindcss, vitejs/vite and withastro/astro, created between 2025-01-01 and 2026-08-22, retrieved via the GitHub GraphQL API. Bot authors excluded by login match (dependabot, renovate, github-actions, crowdin, transifex, and any login containing [bot]). n = 6,947 for 2025 and 5,344 for 2026, 12,291 total. Rate figures are normalized to months: 12.0 for 2025 and 7.65 for 2026.

Statistics. Median comparisons use Mann-Whitney U with a normal approximation. Ratio confidence intervals are bootstrap percentile intervals at 2,000 resamples, seed fixed. Cross-repository consistency uses a two-sided sign test, which with n = 5 cannot return below p = 0.062.

Confounds, in order of how much they should worry you.

Agent authorship is not observable in this data. Agent-written PRs arrive from human accounts. I am comparing 2025 with 2026 and noting that the CLI-agent adoption wave falls in that gap. That is a timing correlation, not attribution. Anything else changing across those years (contributor mix, project maturity, tooling, release cadence) is inside my effect. This is the limitation that matters most, and no amount of extra repositories fixes it.

Threads proxy depth, they do not measure it. A careful review that finds nothing leaves no trace. A pedantic review of a trivial change leaves several. The metric is directionally meaningful in aggregate and unreliable per PR.

Policy moves coverage independently of behaviour. The astro step change is the clear case, and there may be smaller ones I have not spotted.

Public OSS review culture is not commercial review culture. Maintainers can merge their own work; salaried reviewers usually cannot. I would expect the commercial version of this to surface as queue time rather than depth loss, which is exactly what I have observed at clients.

2026-Q3 is partial, covering 1.7 months to August 22. It is the heaviest load quarter in the series and the sparsest in data.

Five repositories, all developer tooling, all TypeScript or Rust. No enterprise codebases, no monorepos, no regulated environments.

Reproduction. The harvest and analysis scripts are four short files: a GraphQL pagination loop and three Python passes for the aggregates, the mechanism table and the significance tests. They run against any repository you can read. The interesting version of this exercise is not my five repositories; it is yours, because the number that should change your process is the one from your own history.

Merge still means what it always meant procedurally. A gate was cleared. What changed is how much reading happens on the way through, and that the change does not appear on anything you are currently watching.

Share this post

If it was useful, pass it along.

What the link looks like when shared.
X LinkedIn Bluesky

Search posts, projects, resume, and site pages.

Jump to

  1. Home Engineering notes from the agent era
  2. Resume Work history, skills, and contact
  3. Projects Selected work and experiments
  4. About Who I am and how I work
  5. Contact Email, LinkedIn, and GitHub