Merge Queue Scopes
Understand how Mergify groups pull requests by scope to build the most effective batches.
Mergify scopes describe the areas of your codebase that a pull request touches. By attaching scopes to pull requests, the merge queue can build smarter batches, reuse the same CI work, and avoid mixing unrelated changes.
Looking to use scopes outside of the merge queue? Check out Monorepo CI for scope-driven CI workflows.
Here’s a quick walkthrough of how we use scopes on Mergify’s own monorepo:
Scope-aware batching at a glance
Section titled Scope-aware batching at a glanceWhen several pull requests are eligible for the next batch, Mergify compares their scopes and prioritizes the combination that shares the most scopes in common. Pull requests that overlap in scope are tested together first, while unrelated changes stay in the queue until a compatible batch is available or Mergify needs them to fill the requested batch size.
In the example above, the queue selects the three pull requests that share the frontend and api
scopes first. The change that only touches the tooling scope is kept aside unless Mergify needs it
later to complete the batch.
How Mergify builds scope-aware batches
Section titled How Mergify builds scope-aware batchesScope-aware batching follows these steps:
-
Collect candidates: Mergify looks at the next pull requests in queue order that pass the queue rules and are ready to batch.
-
Score overlap: It evaluates how many scopes each candidate shares with the already selected pull requests and prefers combinations with the highest overlap.
-
Fill the batch: If the required
batch_sizeis not reached with strongly overlapping scopes, Mergify expands the selection to the best remaining options so the batch can still start. -
Fallback safely: When no scope overlap exists, the queue still batches the oldest pull requests together to honor throughput, but these situations are the exception rather than the rule.
This strategy maximizes CI reuse: tests that run for one pull request are likely valid for the other changes in the batch because they touch the same areas of the codebase.
Scope assignment lifecycle
Section titled Scope assignment lifecycleScopes can be attached to pull requests automatically or manually:
-
File pattern detection: Define scopes directly in your configuration and Mergify evaluates them itself, matching each pull request’s changed files against your patterns. No CI job or GitHub Action is required for the queue to batch by scope. See file-pattern scopes for a step-by-step setup.
-
Manual upload: Use the
gha-mergify-ciGitHub Action, the REST API, or themergify ci scopes-sendCLI to push scopes computed by your own tooling (Nx, Bazel, Turborepo, etc.). Examples are available in the build tool guides under Scopes integrations.
Configuration schema
Section titled Configuration schemaDeclare scopes at the top level of your .mergify.yml file:
scopes: source: files: frontend: include: - apps/web/**/* api: include: - services/api/**/*.py docs: include: - docs/**/* merge_queue_scope: merge-queue
queue_rules: - name: default batch_size: 3Top-level keys
Section titled Top-level keys-
scopes.source: selects how scopes are provided.-
files: map scope names to the file patterns that define them. Each entry acceptsincludeand optionalexcludelists. -
manual: instructs Mergify to expect scopes from external systems via the API or GitHub Action. -
null: disables scopes entirely.
-
-
scopes.merge_queue_scope: optional name automatically applied to temporary merge queue pull requests (defaults tomerge-queue). Set it tonullto disable. -
scopes.capacities: optional map of scope name to the number of speculative checks that scope may run at the same time, used to limit per-scope concurrency in parallel mode. See Limiting concurrency per scope. -
scopes.barrier_files: optional file filters marking files that impact every scope. Only valid with afilessource. A pull request that changes a matching file becomes a merge queue barrier. See Declaring a pull request impacts every scope.
Manual source example
Section titled Manual source examplescopes: source: manual:
queue_rules: - name: default batch_size: 5With the configuration above you must push scopes yourself—typically from a CI job that analyses the
pull request and calls gha-mergify-ci with the scopes-upload action. This is the recommended
approach when build systems such as Bazel, Nx, or Turborepo already know which projects are affected.
Declaring a pull request impacts every scope
Section titled Declaring a pull request impacts every scopeSome pull requests invalidate everything: a build-system configuration change or a shared toolchain bump. Enumerating every scope by hand is brittle, and the list goes stale as soon as your set of scopes changes.
Instead, mark the change as a barrier, a pull request that impacts every scope. Mergify sets an
all_scopes flag on it and serializes the queue around it. How
you set the flag depends on where your scopes come from:
-
File-pattern scopes: declare
scopes.barrier_filesand Mergify sets the flag whenever a pull request changes a matching file. -
Manual scopes: set
all_scopes: truewhen you upload scopes through the API or CLI.
Barrier files (file-pattern scopes)
Section titled Barrier files (file-pattern scopes)When your scopes come from file patterns, declare the files
that impact every scope under scopes.barrier_files. Whenever a queued pull request changes a
matching file, Mergify flags it with all_scopes and treats it as a barrier, with no CI job or
manual upload required.
scopes: source: files: frontend: include: - apps/web/**/* api: include: - services/api/**/*.py barrier_files: include: - .github/workflows/** - Makefile
queue_rules: - name: default batch_size: 3With this configuration, a pull request that changes .github/workflows/** or Makefile (files
that affect the whole repository) becomes a barrier, whichever scopes it also belongs to.
barrier_files accepts the same include and optional exclude patterns as a scope, with two
constraints:
-
At least one
includepattern is required. An empty or exclude-only filter would match every pull request and silently serialize the entire queue, so Mergify rejects it. The same rule lives in the JSON schema, so the dashboard and other config editors catch it too. -
barrier_filesonly works with afilessource. Amanualsource reports the barrier through the API instead (see below), and a configuration with no source has no scopes to impact. Mergify rejectsbarrier_filesin either case.
You can also manage these patterns from the dashboard: the Barrier files editor in the queue
configuration Scopes section edits the same barrier_files filters for file-pattern scopes.
Marking a barrier on upload (manual scopes)
Section titled Marking a barrier on upload (manual scopes)When you upload scopes yourself, set the all_scopes flag on the pull request. With the
Mergify CLI, pass --all to scopes-send:
mergify ci scopes-send -s build-system --allWhen you upload a scopes JSON file with --scopes-json, the CLI also honors an
"all_scopes": true field in the file itself, so your detection tooling can set the flag without
touching the command line.
You can send the flag through the REST API as well:
curl -X PUT \ -H "Accept: application/json" \ -H "Authorization: Bearer <my-application-api-key>" \ -H "Content-Type: application/json" \ -d '{"scopes": ["build-system"], "all_scopes": true}' \ https://api.mergify.com/v1/repos/<owner>/<repository>/pulls/<number>/scopesThe flag complements the scopes list rather than replacing it: keep reporting the concrete
scopes your tooling detected, and set all_scopes: true on top when the change affects every
target.
Barrier behavior in the queue
Section titled Barrier behavior in the queueA pull request flagged with all_scopes conflicts with every scope, so the merge queue treats it
as a barrier:
-
It is never batched with other pull requests and never runs its checks in parallel with other batches.
-
Batches already running when it enters the queue complete first.
-
Every pull request queued behind it waits for it to merge, including pull requests whose scopes first appear after the barrier entered the queue.
-
With per-scope capacities, the barrier consumes one slot in every capped scope.
The queue serializes at the barrier and resumes normal scope-aware batching once the flagged pull
request merges. Because a barrier defeats batching and parallelism, reserve all_scopes for
changes that genuinely require testing against everything.
The flag is visible in the merge queue status API and on the draft pull request description created by the queue.
Best practices
Section titled Best practices-
Keep scope names stable and small in number so batches stay meaningful.
-
Prefer scopes that align with your CI topology—if a test suite covers a specific service or package, create a scope with the same boundary.
-
Still configure sane
batch_max_wait_timevalues: scopes help Mergify pick the right pull requests, but you control how long it waits for an ideal batch. -
Monitor merge queue analytics to verify that scope-aware batching increases success rate and reduces redundant CI runs; adjust scope definitions when you see batches mixing unrelated changes.
Was this page helpful?
Thanks for your feedback!