Optimistic Merge vs Pessimistic Merge Queue Modes
Batching and speculative validation recover throughput without sacrificing main-branch stability.

Merge queues force a bet every engineering team eventually has to make: does a change get validated before it lands on main, or does it land first and get fixed if something breaks? That single choice, pessimistic versus optimistic, shapes throughput, stability, and how much engineering time gets burned on rework. Most teams get this wrong in the same direction: they start pessimistic out of caution, then bolt on optimism only after the queue has become the bottleneck, instead of sizing the strategy to team size and CI reliability from day one. Pessimistic-by-default is the safer-sounding choice, and it's usually the wrong one past a small team size, for reasons that show up in the failure data below.
The failure modes that make the choice consequential
Two specific failure patterns explain why this decision matters more than it looks on paper.
The first is what practitioners call a stealth merge. A pull request passes CI at the moment it's tested, but sits in the queue while other changes land ahead of it. By the time it actually merges, the branch it was tested against no longer exists. The green checkmark is real, but it describes a version of main that's already gone stale. That gap surfaces later as downstream CI breaks, reverts, or, worse, a production incident traced back to a test result that was accurate when it ran and wrong by the time it counted.
The second is the diamond merge, sometimes called a green-green failure. Two pull requests each pass CI independently. Merged together, they break main. The textbook case: one PR renames a helper method, another PR, written and tested in parallel, unaware of the first, adds a new call to the old method name. Both are green in isolation. Neither is green in combination.
The scale of the problem is not flat across team sizes, and this is where most intuition breaks down. Data from the Mergify State of Merge Queues 2026 report, covering 200,000-plus merges across 477 teams, found that a green PR breaks main about 0.77% of the time on teams of 2 to 5 engineers, roughly 1 in 130. At 40-plus engineers, that rate climbs to 12.5%, or 1 in 8. That's an order-of-magnitude jump, not a gentle slope, and it means the cost of "fix it after merge" scales faster than the team does. Pure optimistic merging stops holding up well before an org hits that size. But pure pessimistic queues, run one PR at a time against a static main, still miss diamond failures unless they specifically test combinations of concurrent changes. Serial validation alone is not the safe default it looks like either.
How a serial (fully pessimistic) queue works and where it breaks down
A serial queue is the simplest pessimistic configuration: test each PR alone, in order, against the current state of main, and only merge once it passes. Nothing lands out of order. Main stays green by construction, and diamond merges can't happen because nothing merges in combination.
The problem is arithmetic, plain and unforgiving. If a CI run takes 15 minutes and 10 PRs are sitting in the queue, that's two and a half hours of pure waiting before the last one lands, even if every single one passes on the first try. A 30-minute CI suite in a strictly serial queue caps out at two merges an hour, no matter how many engineers are ready to ship.
Queueing theory has a name for what happens next: as arrival rate approaches service rate, wait times don't creep up, they explode. A team of 50 engineers producing even a modest number of PRs per developer-day can blow past a two-per-hour ceiling without much effort, and once that happens, the queue backs up faster than anyone plans for.
Serial mode still makes sense in a narrow band: CI that's genuinely fast, a team small enough that queue depth rarely exceeds a handful, or a domain where a broken main carries outsized consequences regardless of cost. Outside that band, serial is where a queue should start, not where it should stay. Teams that leave it there past a small team size are paying a latency tax that has nothing to do with code quality and everything to do with an unexamined default.
Speculative checks and batching: where throughput is actually recovered
Speculative checks fix the throughput problem without giving up the pessimistic guarantee. Instead of testing each PR against the current tip of main, the queue tests it against the future state of main: the tip plus everything already ahead of it in the queue.
Concretely, if PRs A, B, and C are queued in that order, the queue tests A against main, tests B against main-plus-A, and tests C against main-plus-A-plus-B, all running at the same time rather than one after another. Each PR gets validated against the branch state it will actually land into, not the stale point where it happened to be written. That single change turns a strictly serial bottleneck into a parallel pipeline.
Batching adds another layer. A queue can build temporary combined branches (draft merges of PR #1, then PR #1 plus PR #2, then PR #1 plus PR #2 plus PR #3), run CI on all of them in parallel, and merge the whole set at once if the batch passes. If a batch fails, the queue can pull the offending change out and continue with the rest instead of throwing away the whole batch.
The gains here are not theoretical. GitHub's internal monorepo, with more than 500 engineers producing roughly 2,500 pull requests a month, moved from a deploy-train model to dynamic merge groups and significantly improved throughput and time-to-ship in the process. The tradeoff is wasted CI: if an early speculative branch fails, everything queued behind it restarts from scratch. That cascade cost is the tension running through every mode that follows, and it's the main argument against treating speculative checks as a free lunch.
Two similarly named ideas are worth separating here. Parallel checks are the speculative CI just described, running within a single ordered queue. Parallel mode is something else entirely: independent, scope-based queues, so a CSS tweak never sits behind an API migration, using build-graph tooling like Bazel, Nx, Turborepo, or Pants, or simple file-pattern matching, to figure out which changes actually touch overlapping code.
The optimistic skip: trusting a later result instead of every intermediate gate
By default, in a batched or speculative queue, every intermediate draft that includes a given PR has to pass before that PR merges. Each draft is a gate, and a PR waits behind all of them.
An optimistic variant relaxes that: a PR merges as soon as a later, more comprehensive draft that includes it passes, even if an earlier intermediate draft failed. A later batch, incorporating more of the eventual state of main, is a better signal than an earlier partial one. Holding a PR hostage to a gate that's already been superseded by a more complete check wastes time for no gain in safety.
This bet only pays off under specific conditions, and it belongs in the "earned, not default" category. It requires a low flake rate, since a passing result only means something if passing reliably means the code works. It requires CI runs expensive enough in wall-clock time that skipping redundant intermediate reruns actually saves something worth having. And it works best paired with batching or speculative checks, where later drafts genuinely do encompass more of the combined future state rather than just repeating the same test against a slightly different snapshot.
Where the bet falls apart: high flake rates, where a passing later draft might be passing by chance rather than by correctness, and heavy AI-authored PR volume. One analysis found AI-co-authored PRs carry roughly 1.7 times more issues than human-only PRs, and some of those issues only surface once the PR combines with others in a merge group, not in isolation. That makes the culprit-finding process slower and turns optimistic skipping into a riskier bet than it would be for pure human-authored traffic. The real decision here isn't a binary switch between two modes. It's a granular policy question about which results a team is actually willing to trust, and most teams never write that policy down at all.
Why agentic PR volume is forcing this decision at scale
Coding agents solved the cheap part of software delivery. Writing a pull request now takes minutes. Landing it safely does not, and that gap is where merge queues are starting to strain.
Teams with heavy AI adoption are merging close to twice as many pull requests as before, and delivery metrics barely move, because the review pipeline, the CI fleet, and the merge queue were all sized for human typing speed, not agent output speed, according to one analysis of delivery patterns in a period of heavy automated code contribution. PR volume has stopped tracking headcount. Merge throughput still tracks something rigid: how many candidate states of main the CI system can actually validate per hour.
The scale some organizations face now would have looked implausible a couple of years ago. OpenAI reportedly runs a million builds a day, and one infrastructure startup, Hermetic, won a contract to handle 500,000 of those builds daily on its own, a volume that reflects how far infrastructure demands have outpaced what most engineering organizations were sized to handle. A 2023 report from LinearB found engineering teams lose an average of 31.6% of active coding hours each week waiting on CI, builds, and deploy queues. That number predates the current wave of agent-generated PR volume, and likely understates the pressure teams are under today.
The data on whether AI-assisted PRs are riskier is genuinely mixed, and it's worth stating plainly rather than smoothing over. The State of Merge Queues 2026 report found AI-assisted PRs broke main about 1.9% of the time versus 4.4% for human-only PRs, though AI PRs were also larger on average (137 changed lines versus 84). That same report frames the finding as an association, not a causal claim. Separately, The Merge Queue Is the New Bottleneck found roughly 1.7 times more issues in AI-co-authored PRs than in human-only ones, some surfacing only in the merge group. The two datasets use different methodologies and don't resolve into one clean verdict. What both point to, regardless of which number wins, is a mechanism worth taking seriously: agents amplify flake exposure simply by generating more queue entries, and an agent instructed to "get this merged" will often retry aggressively, burning CI runs and retriggering cascades for every human behind it in line, at a frequency no person would generate on their own. The merge queue, not the model, is turning into the bottleneck agent-scale development hits first.
Conditions that favor a pessimistic (validate-first) configuration
Pessimistic validation earns its cost when a failure is expensive to undo. At 40-plus engineers, where a green PR breaks main roughly 1 in 8 times, the downstream cost, blocked engineers, wasted CI cycles, emergency reverts, tends to outweigh the latency of validating before merge rather than after.
Flake rate decides this more than any other variable. A high flake rate makes any result untrustworthy, including a later speculative one, which means pessimistic mode at least forces a failure to get investigated before code lands rather than after main is already broken for everyone.
Governance-heavy environments favor pessimistic configuration almost by default: codebases where every commit needs individual auditability, where regulated change management applies, or where the review chain is itself part of a compliance requirement. Browsers, database engines, and operating systems fall into this category for a reason. A broken main in those contexts isn't an inconvenience. It's a liability.
Agent-heavy PR traffic, counterintuitively, makes pessimistic validation more valuable, not less. Agents that retry aggressively generate cascades under any queue mode, but a post-merge rollback from an optimistic miss is harder to attribute and slower to fix than a pre-merge rejection.
A practical hybrid is worth naming here: two-stage CI, where lightweight checks (lint, unit tests, type checking) run directly on the PR, and the full, expensive suite only runs once the PR enters the queue. That preserves the pessimistic guarantee while keeping median latency manageable, and it shows up as a recommended pattern across more than one industry evaluation of queue design.
Plaid's own experience with queue configuration is a useful, concrete data point. At roughly 700 commits a week, with minutes between commits during peak hours, a naive "build everything" configuration pushed median merge queue time to around 6 minutes and p95 past 12 minutes. Scoping down what got rebuilt on each change brought the median down to 1.8 minutes. Pessimistic validation is viable even at that commit velocity, but only once the scope of what gets tested per merge is deliberately narrowed, not left to grow unchecked.
Conditions that favor an optimistic (merge-first or skip-intermediate) configuration
Optimistic configuration makes sense when a post-merge fix costs less than the cumulative latency of blocking every merge on full validation. That's the entire trade, stated plainly, and teams that overthink it past that point are usually solving the wrong problem.
The baseline breakage numbers matter here. Across private repositories, the overall main-breakage rate sits around 5.1%; on open source projects, it drops to 1.1%. Codebases at the lower end of that range can reasonably treat an occasional post-merge fix as cheaper than the latency piled up by gating every PR pessimistically at high volume.
CI stability is non-negotiable as a prerequisite, not a nice-to-have. Skipping intermediate results only makes sense when a passing later draft is a genuinely trustworthy signal, and that requires an actively maintained low flake rate, not an assumption that CI happens to be fine this quarter.
Smaller projects with scarce maintainer time are a natural fit too. The original optimistic-merge framing, land the patch, deal with a styling nit or minor issue afterward, holds up well where reviewer bandwidth is the actual bottleneck rather than breakage risk. A safety net matters here regardless: bisect-on-failure strategies, which split a failing batch and retest to isolate exactly which change caused the break, let teams run optimistic batching without flying entirely blind. High-traffic repos running this kind of strategy have reported meaningful cuts, in the range of 60 to 80%, in queue-related CI minutes within the first month of adoption.
Optimistic strategies get riskier fast under three conditions that increasingly show up together: a high share of PRs from automated tooling, an elevated flake rate, or a codebase with a track record of diamond merges. None of those three are rare in agent-heavy development environments right now, which is exactly why "optimistic" in practice rarely means merge without CI at all. It means trusting the right result and not wasting cycles re-running checks that add no new information.
What flaky tests do to both strategies and why CI hygiene is the prerequisite for either
Uber's monorepo experience is a useful illustration of how much damage a small number of unreliable tests can do. Before the company built dedicated flake management tooling, its iOS mainline was green only 52% of the time, and roughly 1,000 flaky tests were eventually identified out of 600,000 total across its monorepos. A fraction of a percent of unreliable tests was enough to clog the entire queue for every engineer behind it.
Under pessimistic mode, flakes cause retries that delay every merge behind them and slowly erode trust in what a red build even means. Engineers start ignoring failures as noise, which defeats the entire premise of validating before merge in the first place.
Under optimistic mode, the damage takes a different shape. A flake means a "passing" later draft might be passing for the wrong reason entirely, and the whole skip-intermediate-results bet quietly becomes a bet on noise rather than on signal.
Agent volume makes this nonlinear in a way that's easy to underestimate. A flake that fires once every 200 runs, in a queue processing 40 batches a day, produces a cascade roughly once a week. Push that same queue to 120 batches a day, and the same flake rate produces a cascade daily. The flake rate never changed. The exposure did, because agent-driven volume multiplied the number of chances for that flake to fire.
Re-running full test suites on every PR compounds the pain further, since it delays deploys even when only a small slice of the codebase actually changed, and intermittent failures from unrelated commits sitting in the same batch are genuinely hard to debug. That quietly slows every merge that touches the queue. Fixing the flake rate has to come before choosing a queue mode, not after. Reaching for optimistic configuration specifically to route around a flaky CI system is borrowing against a debt that compounds, and it comes due exactly when volume is highest.
Configuring a queue that fits throughput and stability goals at the same time
Start with the breakage question, not the throughput question. What does a broken main actually cost this codebase in blocked engineers, in emergency reverts, in customer-facing incidents? At 40-plus engineers, a green PR breaks main roughly 1 in 8 times, and that single number should anchor the configuration decision rather than get treated as an afterthought.
From there, the sequence runs in order, and skipping steps is where most teams get burned. Fix the flake rate first: neither pessimistic nor optimistic strategies work on top of unreliable CI. Add speculative checks and batching next, since that's where most of the recoverable throughput actually lives, well before anyone touches the riskier skip-intermediate-results setting. Reserve full optimistic skipping for the specific conditions that justify it, low flake rate, expensive CI runs, batching already in place, and treat it as earned, not default. Build a bisect-on-failure safety net before leaning on any optimistic mode at meaningful PR volume, because the safety net is what makes the optimistic bet survivable when it's wrong.
None of this resolves into one universal setting, and it shouldn't. A team of five engineers on a stable codebase with fast CI has almost nothing in common with a 500-engineer monorepo processing agent-generated PRs by the thousand each month. Picking the mode is the easy part. Getting the underlying CI honest enough to trust, in either direction, is the actual work, and it's the part most teams skip.


