Skip to main content

The Merge Queue Is the New Bottleneck

· 8 min read
Tian Pan
Software Engineer

Your coding agents just made writing code the cheapest part of shipping software. They did not make landing it any cheaper. Teams with high AI adoption merge nearly twice as many pull requests as they did before — and their delivery metrics barely move, because every one of those PRs still has to squeeze through the same review pipeline, the same CI fleet, and the same merge queue that was sized for human typing speed. The constraint didn't disappear. It moved downstream, to the narrowest pipe in the system: the serialized path between "approved" and "on main."

This is a classic theory-of-constraints story, and most engineering organizations are living through it right now without naming it. When one developer can direct five or ten agents in parallel worktrees, PR volume stops tracking headcount. But merge throughput still tracks something much more rigid: how many candidate states of main your CI can validate per hour. That number is governed by test suite duration, runner capacity, flake rate, and queue mechanics — none of which got faster when your agents did.

The capacity math that quietly stops working

A merge queue exists to enforce one invariant: main is always green. It does this by testing every PR against the future state of main — the current tip plus everything queued ahead — rather than the stale branch point where the PR was written. That guarantee is exactly what you want when dozens of concurrent changes can interact, and it is exactly what makes throughput expensive: correctness is bought with serialization.

Run the numbers for a serial queue. If your merge-group CI takes 30 minutes end to end, a strictly ordered queue lands at most two PRs per hour — 48 per day if nothing ever fails. A 50-person team producing two PRs per developer-day already exceeds that. Now let each developer run a couple of agents and the arrival rate triples while the service rate stays fixed. Queueing theory is unforgiving here: when arrivals approach capacity, wait times don't grow linearly, they explode. The queue that added ten minutes of latency last quarter adds four hours this quarter, and nothing about the CI got slower.

Batching is the standard escape hatch, and it genuinely works: test five PRs together in one 30-minute run and you've bought 5x throughput — 30 minutes of compute instead of two and a half hours. GitHub's own monorepo is the reference case. Over 500 engineers merge about 2,500 PRs a month through merge queue; moving from their old deploy-train model to dynamic merge groups cut average time-to-ship by a third and doubled how many changes deploy together safely. But batching has a failure mode, and agents are unusually good at triggering it.

Agents are a flake amplifier

When a batch fails, the queue must find the culprit. The naive strategy ejects the whole batch and retests everything; smarter queues bisect, which still costs O(log n) full CI runs. Either way, one red test invalidates the speculative state that every PR behind it was tested against, and the queue restarts from the failure point. This cascade is the single most expensive event in merge-queue operations — and its frequency is set by your flaky-test rate, not your code quality.

Uber's numbers make the stakes concrete: before they built dedicated flake management, their iOS mainline was green only 52% of the time, and they eventually identified roughly a thousand flaky tests across 600,000 in their monorepos. A fraction of a percent of unreliable tests was enough to clog the queue for everyone.

Agents make this dramatically worse, for three compounding reasons:

  • More entries, more dice rolls. If a flake fires once per 200 runs and your queue processes 40 batches a day, you cascade every week. At 120 batches a day, you cascade daily. The flake rate didn't change; the exposure did.
  • Agents retry into oblivion. A human who sees a spurious failure sighs, clicks re-run, and mentions it in Slack. An agent instructed to "get the PR merged" will re-queue the same change repeatedly, burning full CI runs on each attempt and re-triggering the same cascade for everyone behind it. Retry loops that were mildly wasteful at human frequency become a denial-of-service at agent frequency.
  • AI-authored changes carry more latent breakage. Cross-tool studies have found AI-co-authored PRs contain roughly 1.7x more issues than human-only ones. Some of those issues surface only in the merge group — which means more legitimate failures interleaved with flakes, making culprit-finding slower and optimistic strategies riskier.

The compounding is the point. Each factor alone is manageable; together they turn a queue that hiccuped monthly into one that thrashes continuously. Teams experience this as "CI got flaky," but the tests didn't change — the traffic did.

Why "just add runners" is the wrong first move

Loading…
References:Let's stay in touch and Follow me for more thoughts and updates