Imagine a restaurant kitchen that only starts cooking the next order after the previous one is fully plated and served. That kitchen would be painfully slow. Real kitchens start multiple orders in parallel, betting that most dishes will turn out fine. Merge queues use the same strategy.
The Bottleneck
If you have 10 PRs and each CI run takes 10 minutes, testing them purely sequentially would take 100 minutes. The last developer has to wait over an hour to see their code merge. This is unacceptable at any reasonable engineering velocity.
Predicting the Future
Optimistic Merging (also called Speculative Execution) assumes that most tests will pass. Instead of waiting for PR #1 to finish before starting PR #2, the queue creates a chain of speculative branches immediately and runs them all in parallel:
- Job 1: Tests
main + PR1 - Job 2: Tests
main + PR1 + PR2 - Job 3: Tests
main + PR1 + PR2 + PR3
All three jobs start simultaneously.
Scenario A — Everything Passes:
After 10 minutes, all jobs finish. All 3 PRs merge instantly. Total wall-clock time: 10 minutes instead of 30.
Scenario B — PR2 Fails:
- Job 1 passes → PR1 merges to main.
- Job 2 fails → PR2 is ejected.
- Job 3 is invalidated because it was built on top of PR2. It must be restarted.
- The queue rebuilds: new Job 3 tests main + PR1 + PR3.
Timeline (10-min CI):
Without Optimistic Merging:
0:00 ──[PR1 test]──► 0:10 ──[PR2 test]──► 0:20 ──[PR3 test]──► 0:30 (done)
With Optimistic Merging:
0:00 ──[PR1 test]──────────────────────────────────────────────► 0:10 (done)
0:00 ──[PR1+PR2 test]──────────────────────────────────────────► 0:10 (done)
0:00 ──[PR1+PR2+PR3 test]──────────────────────────────────────► 0:10 (done)
The Cost of Optimism
Optimistic merging trades CI compute for developer time. When a PR fails mid-queue, you waste the compute spent on all downstream speculative jobs. For a queue of depth n with a failure at position k, you discard n - k CI runs. This is almost always the right trade-off — CI compute is cheap; developer waiting time is expensive.