Skip to content
Guide

Do I need a merge queue if my CI is fast?

Yes, once your team merges more than a few pull requests a day. Fast CI shortens each run, but each run still tests the main the pull request branched from, so two green pull requests can land and break main. A merge queue tests what will actually land.

By Julien Danjou, Co-founder & CEO of MergifyUpdated

In one paragraph

Faster runners fix how long you wait for CI. They do not change what CI tested. A pull request is checked against main as it was at its last run, and it merges onto main as it is now. The gap between the two is mostly review and waiting time, so cutting a 30-minute pipeline to 2 minutes barely closes it. A merge queue closes it by testing each pull request on the latest main plus everything ahead of it. Fast CI and a queue also multiply: the shorter the run, the more pull requests the queue can clear in an hour.

What can fast CI not catch?

Merge skew, also called a semantic conflict: two changes that are each fine, merge without a conflict, and do not work together. Here is one on a repository with very fast CI:

09:00  main has charge(order)
09:10  PR #41 changes it to charge(order, currency)     CI green
09:15  PR #42 adds a refund flow that calls charge(order)  CI green
11:20  #41 merges. No conflict: git sees different files.
11:45  #42 merges. No conflict.
11:46  main fails to build: refund calls charge() with a missing argument.

Every check was green and git never complained. No run ever saw #41 and #42 together, because no run was asked to. A CI that finished in ten seconds would have reported the same two green checks, a little sooner.

Doesn't faster CI at least shrink the risk?

A little. A pull request is exposed from the moment its last CI run started until it merges, and most of that time is spent waiting for a reviewer. These numbers are illustrative, for a pull request that merges three hours after its last run finishes:

CI durationReview and waitingExposed to skewReduction
30 minutes3 hours3 h 30 minbaseline
10 minutes3 hours3 h 10 min10%
2 minutes3 hours3 h 02 min13%

A 15-fold faster pipeline takes 13% off the window. Your own number is easy to get: compare the merge time of your last twenty pull requests with the time of their last CI run. Whatever merged inside that gap went untested against them.

Fast CI is still worth having, for everything else it does. It answers a different question:

QuestionFaster CIMerge queue
How long until a developer hears back?Shorter on every pushNo change
What does each run cost?Less time per runFewer runs, through batching
Was the pull request tested on the main it lands on?Only if nothing merged since its last runYes
Can two green pull requests break main?YesNo, the second one fails in the queue and never lands

Isn't "Require branches to be up to date" enough?

On a quiet repository, yes, and it is free. GitHub's strict status checks refuse the merge until the branch contains the latest main, which closes the gap. Fast CI makes this setting bearable for longer, because each update costs less.

The cost is coordination. Every merge makes all the other open pull requests out of date, so someone has to update one, wait for CI, and hope nobody else merges first. With five-minute CI, that is twelve merges an hour at the very best, with a person watching each one. A queue runs the same check and takes over the updating, the ordering and the waiting.

When do I not need one?

Skip it if you merge fewer than about five pull requests a day and main rarely breaks from changes in flight. Small repositories with one team fit this, and a queue would be solving a problem they do not have. Pulling main before you push, or turning on the strict setting above, will carry you.

Add one when any of these show up:

  • Main goes red and every pull request merged that day has a green check. This is the direct signal, and it is worth going through a month of main failures to count them.
  • People rebase and re-run CI just to get a merge in, or wait for a quiet moment to press the button.
  • Your merge volume went up without the team growing, which is what coding agents do to a repository. More pull requests in flight means more overlap between them.
  • A red main stops everyone, so a break costs far more than the one person who has to revert.

The merge queue guide covers how the queue works, and Mergify vs GitHub merge queue covers which one fits.

What does fast CI do for a merge queue?

It sets the speed limit. A queue that tests one batch at a time clears one batch per CI run, so a shorter run is more merges per hour. Teams with fast CI get the most out of a queue:

CI durationMerges per hour, one at a timeMerges per hour, batch_size: 5
30 minutes210
10 minutes630
2 minutes30150

That is the ceiling for one lane with every run passing. Parallel checks raise it further, and a failing batch lowers it while the queue bisects. The setup is one setting:

queue_rules:
  - name: default
    batch_size: 3

Your required checks and approvals stay in your branch's ruleset on GitHub, and the queue applies them. Queue a pull request by commenting @mergifyio queue. Your CI keeps running on your runners. The queue only decides what gets tested, and Direct Merge skips the run entirely when a pull request already contains the tip of main. Setting up a merge queue on GitHub has the full walkthrough.

If your CI is not as fast as you would like, finding your slowest CI jobs is the place to start, and testing AI-generated pull requests covers the setup for teams whose volume comes from agents.

FAQ

What is merge skew?

Merge skew is the gap between what CI tested and what actually lands. A pull request is tested against main as it was at its last run, and it merges onto main as it is now. When something merged in between changes the behavior it relies on, you get a semantic conflict: git reports nothing, both pull requests are green, and main is broken.

Is a semantic conflict the same as a merge conflict?

No. A merge conflict is two changes touching the same lines, and git stops you. A semantic conflict is two changes that merge cleanly and do not work together, such as a function signature changing in one file while a new caller appears in another. Git has no way to see it, only a test run on the combined code does.

Does GitHub's 'Require branches to be up to date' setting solve this?

Yes, for a small repository. Each merge makes every other open pull request out of date, so someone has to update it and wait for CI again before it can merge. A queue does the same safety check and handles the updating and the ordering for you.

Will a merge queue slow down my fast CI?

A pull request waits for its turn and for one more CI run, and on a busy day batching and parallel checks are what keep that wait short. On a quiet day it adds nothing: a pull request that already contains the tip of main merges straight away, with no queue run.

Do I have to change CI providers or runners to use a queue?

No. The queue decides what gets tested and in what order. Your CI, on your runners, does the testing, on a draft pull request the queue opens. A faster runner makes the queue faster, so the two work together. Mergify requires GitHub as the code host.

Last updated:

Keep the fast CI. Stop breaking main.

Add a merge queue in front of main and your CI tests what actually lands. Free for up to 5 users.