Stacked Pull Requests
How the Merge Queue lands GitHub-native stacked pull requests and Mergify Stacks: bottom-up landing, auto-propagation, stack-aware batching, and cascade dequeue.
The Merge Queue lands stacked pull requests: chains where each pull request builds on the one below it. It handles both kinds of stack.
-
GitHub-native stacked pull requests, created with gh-stack. Every member can be queued, and members land one at a time from the bottom up.
-
Mergify Stacks, created with
mergify stack push. The queue treats the whole chain as a unit: it propagates the queue command up the stack, keeps stacked PRs together when batching, and cascades failures so the rest of the stack stops cleanly when something breaks.
GitHub-Native Stacked Pull Requests
Section titled GitHub-Native Stacked Pull RequestsGitHub has its own stacking model, built with
gh-stack, its stacking extension for the gh
CLI. Each member is a separate branch targeting the branch below it.
GitHub has no auto-merge for stacked pull requests, so without a queue each member is merged by hand as the one below it lands.
Queueing Members
Section titled Queueing MembersEvery member of a GitHub-native stack can be queued. Comment
@mergifyio queue on each pull request you want to land.
Mergify enqueues them all, keeps same-stack members together in the queue,
and enforces their order on admission, so a member is never validated ahead
of the members below it.
How the Stack Lands
Section titled How the Stack LandsMembers land one at a time, from the bottom up. When the lowest open member merges, GitHub restacks the rest of the chain onto the base branch and the next member becomes the one to land. Merged members stay in the stack on GitHub, so the stack never shrinks.
Because members land one at a time, a stack can be partly landed while the rest is still in flight. If a member fails, the members that already merged below it stay merged.
Requirements
Section titled RequirementsMergify must be a bypass actor with the exempt bypass mode on every GitHub
ruleset that applies to the base branch. With any other bypass mode, the
Merge Queue refuses the pull request. See GitHub Rulesets
Compatibility for how to set it.
Mergify Stacks
Section titled Mergify StacksMergify Stacks are created with mergify stack push, which maps
each commit on a single branch to its own pull request. The queue treats such
a stack as one unit.
How a Stack Is Detected
Section titled How a Stack Is DetectedThe queue recognizes a stack only when both signals hold at every step:
-
The PRs are physically chained: each PR’s base branch is the previous PR’s head branch.
-
Each PR carries a
Depends-On: #Nmarker in its body, declaring its dependency on the previous PR.
This is exactly what mergify stack push produces. PRs
chained only by branch refs (for example, GitFlow promotion chains like
dev → staging → prod) are not treated as a stack. Without the
Depends-On: marker, the queue keeps each PR’s literal base ref and queues
them independently.
Queueing a Whole Stack at Once
Section titled Queueing a Whole Stack at OnceRun @mergifyio queue on the top PR of a stack and the
queue command propagates synthetically to every predecessor. The whole stack
enters the queue from a single comment. You don’t need to comment on each
PR.
For a stack PR1 → PR2 → PR3, commenting @mergifyio queue on PR3 enqueues
PR1, PR2, and PR3 in the right order. While PR3 waits for its predecessors to
join the queue, its checks display the condition
stack-predecessor-queued as pending. That’s the queue holding PR3 back
until PR1 and PR2 are queued ahead of it.
Stack-Aware Base
Section titled Stack-Aware BaseEvery stacked PR is queued against the stack root (e.g. main), not its
immediate parent branch. Without this, PR2 would be queued against PR1’s head
branch and could never reach main, so the queue would have nothing to merge
into.
You don’t configure this. It’s automatic for any PR detected as part of a stack.
Stack-Aware Batching
Section titled Stack-Aware BatchingThe queue treats a stack as an ordered chain when assembling batches. Two guarantees hold:
-
Same scope group. With scopes enabled, stacked PRs are consolidated into the scope group of the bottom PR, even if their individual scopes differ. The stack always travels through the same CI lane rather than getting split across unrelated lanes.
-
Bottom-up order. Within that group, predecessors always queue ahead of successors. PR3 is never validated before PR1 and PR2.
In sequential batching, the queue actively packs a stack into the same batch
when its predecessors still fit in the remaining capacity. In parallel
checks, a stack longer than batch_size (or a stack sharing its scope group
with higher-priority unrelated PRs) lands across consecutive batches. Order
is preserved either way.
A PR only joins a batch if it and its still-waiting predecessors fit inside
the remaining capacity. When the stack is larger than batch_size, it lands
across consecutive batches bottom-first: the first batch validates the deepest
PRs that fit, and once they merge they drop out of the predecessor set, so the
next batch picks up where the previous one stopped.
Cascade Dequeue
Section titled Cascade DequeueIf any PR in a queued stack fails validation or is dequeued, every successor
still in the queue is dequeued automatically with the reason
StackPredecessorDequeued. This stops the queue from validating PRs whose
dependency just broke. There’s no point checking PR3 if PR1 just failed.
After fixing the broken PR, re-queue the stack from the top with
@mergifyio queue. Propagation re-enqueues the predecessors as needed.
Limits
Section titled Limits-
Maximum stack depth: 20. Stacks deeper than 20 PRs aren’t recognized as a stack by the queue and fall back to per-PR queueing.
-
Drafts break the stack. A draft predecessor blocks queue propagation: the queue won’t pull a stack through a PR still marked as draft. Mark the PR ready for review first.
Related
Section titled Related-
Stacks: create and update stacks with
mergify stack push. -
@mergifyio queue: the command that triggers stack propagation. -
Batches: batch-size and CI-cost trade-offs.
-
Scopes: how stacks interact with monorepo scopes.
-
GitHub Rulesets Compatibility: the
exemptbypass mode GitHub-native stacks require.
Was this page helpful?
Thanks for your feedback!