Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions public/_redirects
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,6 @@
/ci-insights/test-frameworks/* /test-insights/test-frameworks/:splat 301
/ci-insights/quarantine /test-insights/quarantine 301
/ci-insights/quarantine/ /test-insights/quarantine 301
/merge-queue/parallel-scopes /merge-queue/queue-modes 301
/merge-queue/parallel-scopes/ /merge-queue/queue-modes 301

4 changes: 2 additions & 2 deletions src/content/docs/merge-queue/merge-strategies.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ commits** from folding each PR into the batch branch.
- **`commit_message_format` has no effect** — fast-forward preserves
the original commits, so custom commit messages are not applicable

- **[Parallel mode](/merge-queue/parallel-scopes) is not supported** — fast-forward
- **[Parallel mode](/merge-queue/queue-modes) is not supported** — fast-forward
is not compatible with scope-based parallel queues

- **Use case:** teams and OSS projects that care about commit identity and want
Expand Down Expand Up @@ -297,7 +297,7 @@ were included in the batch (e.g., "Merge queue: merged #42, #43, #44").
- **Requires `batch_size > 1`** — this method is designed for batch merging and
cannot be used with single PRs

- **Not compatible with [partition rules](/merge-queue/parallel-scopes)**
- **Not compatible with [partition rules](/merge-queue/queue-modes)**

- **Use case:** teams that use batch merging and want a single merge commit per
batch on the base branch, triggering only one deployment per batch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ In parallel mode, PRs touching different scopes are tested and merged
simultaneously — just like partition lanes, but with smarter dependency tracking
when scopes overlap.

See [Parallel Scopes](/merge-queue/parallel-scopes) for details.
See [Queue Modes](/merge-queue/queue-modes) for details.

## Using a Build Tool Instead of File Patterns

Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/merge-queue/monorepo.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ of how you compute them.
- [Scopes reference](/merge-queue/scopes): schema, file-pattern setup, and tooling guides (Nx, Bazel,
Turborepo, custom uploaders).

- [Parallel Scopes](/merge-queue/parallel-scopes): once scopes are configured, enable parallel scopes to
- [Queue Modes](/merge-queue/queue-modes): once scopes are configured, enable parallel mode to
test and merge pull requests that touch different scopes simultaneously — significantly reducing
merge times in monorepos.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
---
title: Parallel Scopes
description: Run independent pull requests through the merge queue simultaneously to merge faster in monorepos.
title: Queue Modes
description: Choose how the merge queue schedules pull requests — serial, parallel, or isolated.
---

By default, Mergify's merge queue operates in **serial mode**: every pull request is tested on top
of the previous one, forming a single ordered pipeline. This guarantees correctness but means
unrelated changes wait for each other.
The `merge_queue.mode` option controls how the merge queue schedules pull requests. There are three
modes:

**Parallel mode** removes that constraint. When two pull requests touch different areas of the
codebase — different **scopes** — Mergify tests and merges them independently, at the same time. Pull
requests that do share a scope are still queued together so they are tested as a group, preventing
semantic conflicts.
- **`serial`** (default) — every pull request is tested on top of the previous one, in a single
ordered pipeline.

Check failure on line 10 in src/content/docs/merge-queue/queue-modes.mdx

View workflow job for this annotation

GitHub Actions / lint

Unexpected `0` blank lines between list items, expected `1` blank line, add `1` blank line
- **`parallel`** — pull requests that touch different [scopes](/merge-queue/scopes) are tested and
merged at the same time.

Check failure on line 12 in src/content/docs/merge-queue/queue-modes.mdx

View workflow job for this annotation

GitHub Actions / lint

Unexpected `0` blank lines between list items, expected `1` blank line, add `1` blank line
- **`isolated`** — every batch runs as a fully independent unit, with no dependency on any other
batch.

:::tip
Parallel mode is designed for monorepos and large repositories where pull requests frequently
change independent parts of the codebase. If most of your pull requests touch the same files,
serial mode with [batching](/merge-queue/batches) may be a better fit.
:::
All three honor your [queue rules](/merge-queue/rules) and [batch sizing](/merge-queue/batches).
They differ only in **how batches depend on each other**.

## Choosing a mode

**Isolated mode** goes one step further. Every batch runs as a fully independent unit with no
dependency on any other batch — even when their changes overlap. Scopes become optional: when set,
Mergify groups similar pull requests into the same batch; when omitted, it batches by priority and
arrival order. See [Isolated Mode](#isolated-mode) below.
| Mode | Batches depend on each other? | Requires scopes? | Best for |
|------|-------------------------------|------------------|----------|
| `serial` | Yes — each batch builds on the previous one | No | Most repositories; pull requests that often touch the same code |

Check failure on line 23 in src/content/docs/merge-queue/queue-modes.mdx

View workflow job for this annotation

GitHub Actions / lint

Unexpected `129` character line, expected at most `120` characters, remove `9` characters
| `parallel` | Only when their scopes overlap | Yes | Monorepos where pull requests usually touch independent areas |
| `isolated` | Never | No | Independent pull requests where you want maximum throughput |

## Serial, Parallel, and Isolated at a Glance
The rest of this page describes each mode in turn. Serial is the default, so if you do nothing you
are already using it.

In **serial mode**, every batch depends on the one before it. Even if PR #3 (docs) has nothing in
common with PR #1 (api) or PR #2 (frontend), it still waits:
## Serial Mode

Serial mode is the **default** — you don't need to configure anything to use it. Every pull request
is tested on top of the one before it, forming a single ordered pipeline. This guarantees
correctness: each pull request is validated against the exact state it will merge into. The
trade-off is that unrelated changes still wait for each other.

```dot class="graph"
strict digraph {
Expand All @@ -47,8 +53,34 @@
}
```

In **parallel mode**, Mergify groups pull requests by scope. Batches that share no scope run at the
same time:
Even though PR #3 (docs) has nothing in common with PR #1 (api) or PR #2 (frontend), it still waits
behind them.

You can set it explicitly, though it is the default:

```yaml
merge_queue:
mode: serial
```

Serial mode still uses [batches](/merge-queue/batches) and
[parallel checks](/merge-queue/parallel-checks) to increase throughput without giving up cumulative
testing. If most of your pull requests touch the same files, serial mode is usually the right
choice.

## Parallel Mode

Parallel mode tests and merges pull requests that touch different areas of the codebase — different
[scopes](/merge-queue/scopes) — at the same time. Pull requests that share a scope are still queued
together so they are tested as a group, preventing semantic conflicts.

:::tip
Parallel mode is designed for monorepos and large repositories where pull requests frequently
change independent parts of the codebase. If most of your pull requests touch the same files,
serial mode may be a better fit.
:::

Batches that share no scope run at the same time:

```dot class="graph"
strict digraph {
Expand Down Expand Up @@ -104,43 +136,12 @@
Here PR #4 touches the `api` scope, just like PR #1 — so it must wait for PR #1 to merge first.
Meanwhile PR #3 (docs) proceeds independently.

In **isolated mode**, there are no dependencies at all. Every batch runs on its own, even when two
batches touch the same code, so an overlap like the one above never creates a wait:

```dot class="graph"
strict digraph {
fontname="sans-serif";
rankdir="TB";
label="Isolated Mode\nEvery Batch Independent";
nodesep=0.8;
ranksep=0.6;

node [shape=box, style="rounded,filled", fontcolor="white", fontname="sans-serif", margin="0.3,0.18"];
edge [style=invis];

subgraph cluster_running {
style="rounded,filled";
fillcolor="#1CB893";
color="#1CB893";
fontcolor="#000000";
label="Tested simultaneously";

PR1 [label="Batch 1\nPR #1", fillcolor="#347D39"];
PR2 [label="Batch 2\nPR #2", fillcolor="#347D39"];
PR3 [label="Batch 3\nPR #3", fillcolor="#347D39"];
}

{ rank=same; PR1; PR2; PR3; }
}
```

## Setting Up Parallel Mode
### Set up parallel mode

Parallel mode requires two things: switching the queue mode and configuring
[scopes](/merge-queue/scopes) so Mergify knows which areas of the codebase each pull request
touches.
Parallel mode requires two things: configuring [scopes](/merge-queue/scopes) so Mergify knows which
areas of the codebase each pull request touches, and switching the mode.

### 1. Define scopes
#### 1. Define scopes

Scopes can come from file patterns declared directly in `.mergify.yml`, or from an external build
system (Nx, Bazel, Turborepo, …) via the
Expand All @@ -163,7 +164,7 @@

See [Scopes](/merge-queue/scopes) for all configuration options and build-tool integrations.

### 2. Enable parallel mode
#### 2. Enable parallel mode

Add `mode: parallel` under `merge_queue`:

Expand Down Expand Up @@ -195,7 +196,7 @@
The `max_parallel_checks` setting controls how many batches Mergify tests at the same time across
all scope queues. Tune it to match your CI capacity.

## How It Works
### How parallel mode works

Once parallel mode is active, the merge queue follows these steps whenever it processes pull
requests:
Expand All @@ -216,16 +217,12 @@
5. **Merge.** As soon as a batch's CI passes and all its parent batches are merged, Mergify merges
the pull requests in that batch.

### What happens when a batch fails?

The failure handling works the same way as in serial mode: Mergify splits the failed batch and
retests the parts to isolate the problematic pull request. See
[Handling Batch Failures](/merge-queue/batches#handling-batch-failure-or-timeout) for details.

Because batches in parallel mode are scoped, a failure in one scope queue does **not** block
unrelated scope queues. Only batches that depend on the failed one (via shared scopes) are affected.
When a batch fails, Mergify splits it and retests the parts to isolate the problematic pull request
(see [Handling Batch Failures](/merge-queue/batches#handling-batch-failure-or-timeout)). Because
batches are scoped, a failure in one scope queue does **not** block unrelated scope queues — only
batches that depend on the failed one (via a shared scope) are affected.

## The Monorepo Trade-Off
### The monorepo trade-off

Parallel mode is built for the reality of monorepos: most pull requests are independent, but some
do interact.
Expand All @@ -246,6 +243,33 @@
entirely: every batch is a self-contained unit that is tested and merged on its own, with no parent
batch and no child batch. A failure in one batch never blocks any other.

```dot class="graph"
strict digraph {
fontname="sans-serif";
rankdir="TB";
label="Isolated Mode\nEvery Batch Independent";
nodesep=0.8;
ranksep=0.6;

node [shape=box, style="rounded,filled", fontcolor="white", fontname="sans-serif", margin="0.3,0.18"];
edge [style=invis];

subgraph cluster_running {
style="rounded,filled";
fillcolor="#1CB893";
color="#1CB893";
fontcolor="#000000";
label="Tested simultaneously";

PR1 [label="Batch 1\nPR #1", fillcolor="#347D39"];
PR2 [label="Batch 2\nPR #2", fillcolor="#347D39"];
PR3 [label="Batch 3\nPR #3", fillcolor="#347D39"];
}

{ rank=same; PR1; PR2; PR3; }
}
```

Use isolated mode when your pull requests are genuinely independent and you want maximum throughput
without maintaining a scope map — for example when each pull request targets its own service or
package and you don't need Mergify to serialize overlapping changes.
Expand All @@ -266,42 +290,29 @@
- check-success = ci
```

### How batches form
### How isolated batches form

How Mergify fills a batch depends on whether you configure
[scopes](/merge-queue/scopes):
How Mergify fills a batch depends on whether you configure [scopes](/merge-queue/scopes):

- **With scopes.** Mergify groups the most similar pull requests — those sharing the most scopes —
into the same batch, using the same [scope-aware batching](/merge-queue/scopes) as the other
modes. This keeps related changes tested together and maximizes CI reuse.

- **Without scopes.** Mergify fills batches by queue priority and arrival order, up to `batch_size`.

Either way, the batches that result are fully independent. They run concurrently up to
Either way, the resulting batches are fully independent. They run concurrently up to
`max_parallel_checks`, and Mergify merges each one as soon as its own CI passes — there is never a
parent batch to wait for.

### Isolated vs. parallel

| | Parallel mode | Isolated mode |
|--|--|--|
| Scopes | Required | Optional |
| Cross-batch dependencies | Yes, when scopes overlap | Never |
| A batch can block another | Yes (shared scope) | No |
| Batch formation | By shared scopes | By shared scopes, or by priority + arrival order when no scopes |

Batch failure handling is the same as in the other modes: Mergify splits the failed batch and
retests the parts to isolate the culprit. See
[Handling Batch Failures](/merge-queue/batches#handling-batch-failure-or-timeout).
parent batch to wait for. Batch failures are handled the same way as in the other modes (see
[Handling Batch Failures](/merge-queue/batches#handling-batch-failure-or-timeout)).

## Compatibility and Limitations

Parallel and isolated modes change how the queue operates. Some features that rely on strict
single-queue ordering are not available:

- **Scopes are required in parallel mode.** You must configure `scopes.source` (either `files` or
`manual`) so Mergify can tell which pull requests are independent. Isolated mode does not require
scopes — see [Isolated Mode](#isolated-mode).
`manual`) so Mergify can tell which pull requests are independent. Serial and isolated modes do
not require scopes.

- **`fast-forward` merge is not supported.** Because batches merge independently, Mergify needs to
rebase them. Use `merge` or `rebase` as your `merge_method`.
Expand Down
Loading
Loading