in GitLab: when they pay off
The more merge requests race against the same protected branch at the same time, the greater the risk that two individually well tested changes break each other once merged. Merge trains solve this by testing every merge request not against the current state but against the expected future state of the target branch, sequentially, one after another, like carriages on a train.
Table of Contents
- 1. The problem of concurrent merges into one branch
- 2. How a merge train actually works
- 3. Activation and requirements
- 4. Semi-linear history as a side effect
- 5. The actual cost of merge trains
- 6. When merge trains actually pay off
- 7. When merge trains do not pay off
- 8. Alternatives and intermediate steps
- 9. Conclusion: merge trains as a targeted tool, not a default setting
- 10. Summary
- 11. FAQ
1. The problem of concurrent merges into one branch
Even if two merge requests each individually passed a successful merge request pipeline, that does not guarantee both work together once they are merged one after another into the same target branch. Merge request A tests against the current state of main, merge request B also tests against the current state of main, but neither test accounts for what main looks like after both have been merged. If both changes touch the same part of the code or interact with each other's logic, main can end up broken after both merges, even though each individual merge request had a green pipeline on its own.
This problem, often called a semantic merge conflict, occurs more frequently the more merge requests race against the same branch at once and the higher the merge frequency. In teams merging several merge requests into main multiple times a day, especially on protected branches with strict green-pipeline requirements before every merge, this problem quickly becomes a real operational nuisance, because the target branch regularly ends up broken despite every individual check, requiring an after-the-fact fix commit.
2. How a merge train actually works
A merge train is an ordered queue of merge requests, all destined for the same protected branch. As soon as a merge request joins the merge train, GitLab creates a simulated state that combines not only the feature branch with the current target branch, but also every merge request already queued ahead of it in the train that has not yet been merged. So the second merge request in the train is not tested against today's main, but against a state of main as it would look if the first merge request in the train had already been merged successfully.
Only once the pipeline for this combined, simulated state passes does the merge request actually get merged into the real target branch, and the next merge request in the train advances accordingly. If the pipeline fails for a merge request in the train, exactly that merge request is removed from the train, and every subsequent merge request in the train is automatically retested, now without the failed merge request in its simulated base, so a broken merge request cannot block the entire queue or even end up corrupting the target branch.
workflow:
rules:
- if: '$CI_MERGE_REQUEST_EVENT_TYPE == "merge_train"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
test_in_train:
stage: test
script:
- vendor/bin/phpunit
rules:
- if: '$CI_MERGE_REQUEST_EVENT_TYPE == "merge_train"'
3. Activation and requirements
Merge trains are a GitLab Premium and Ultimate tier feature and are not available on the free tier, which is an important constraint when weighing cost against benefit. The feature is enabled in the project settings under Merge requests via the Enable merged results pipelines option followed by Enable merge trains, with merged results pipelines being a technical prerequisite for merge trains, since both rely on the same mechanism for computing a simulated merge state.
Additionally, the target branch must be configured as a protected branch with the pipeline-success requirement for merges enabled, since a merge train without this prerequisite would make no sense: the entire mechanism exists specifically to automatically ensure that only changes tested green ever reach the protected branch. For runner capacity, enabling this also means that at high merge frequency, several complete pipeline runs may run simultaneously or in quick succession, which requires sufficient runner capacity so merge request authors are not additionally slowed down by long queues for a free runner.
4. Semi-linear history as a side effect
An often underrated benefit of merge trains is their effect on the target branch's git history: because every merge request in the train is merged one after another rather than in parallel, a semi-linear history results on the target branch, where every merge commit genuinely builds on the immediately preceding commit instead of interleaving several parallel merge commits created at the same time. This property significantly eases later bisecting during debugging, because git bisect works much more reliably on a semi-linear history than on one with many overlapping merge commits whose relative order is ambiguous.
This semi-linear history is also valuable for audits and compliance requirements, because it lets you unambiguously trace, for every commit on the protected branch, exactly what state the branch was in at the time of that merge and which pipeline tested exactly that state. In industries with strict traceability requirements, such as finance or healthcare, this side effect is sometimes even the actual main reason for introducing merge trains, more important than merely avoiding semantic merge conflicts.
5. The actual cost of merge trains
The most obvious cost factor is that a merge train runs a full pipeline against the combined simulated state for every merge request in the train, and these pipelines have to be partially rerun whenever the train changes, for example when an earlier merge request fails. With a train of five waiting merge requests and a typical pipeline runtime of ten minutes, the effective wait time for the last merge request in the train can grow considerably compared to a single, isolated merge request pipeline run without a queue.
This effect intensifies if pipelines fail regularly in practice, because every failure in the train triggers a recalculation for all subsequent merge requests. Teams with an unstable test suite that frequently contains flaky tests, tests that sometimes pass and sometimes fail without any content change, often experience a noticeably worse experience with merge trains than without, because test instability compounds through the chain reaction in the train instead of staying isolated. Merge trains therefore only pay off once the underlying pipeline is already reliable and fast.
6. When merge trains actually pay off
Merge trains deliver the most value in teams with several active contributors, a high daily merge frequency onto a single protected branch, and an already stable, comparatively fast pipeline running from a few minutes up to roughly ten to fifteen minutes at most. In this setup, the risk of semantic merge conflicts is real and the cost of the additional sequential test run per merge request is manageable, because the short pipeline runtime keeps the queue from growing out of control.
An additional, often decisive criterion is the actual history of broken main branches: teams that have already repeatedly experienced main breaking despite every individually green merge request pipeline, because two changes merged in parallel interfered with each other, have the clearest evidence for the value of merge trains. Anyone who has never experienced this problem, because merge frequency is already low or merges are usually spread far apart in time, should critically question the extra configuration and wait-time overhead before introducing merge trains.
7. When merge trains do not pay off
For small teams with few contributors, low merge frequency, or pipelines running longer than fifteen to twenty minutes, the effort for merge trains is usually not justified. Long pipeline runtimes combined with a queue mean developers at the end of a train may have to wait several hours for their actual merge, which undermines the motivation to submit small, frequent merge requests in the first place and paradoxically leads to larger, less frequently submitted merge requests that make the original problem worse rather than better.
For projects without an actual Premium or Ultimate license, the option is unavailable anyway, and upgrading the GitLab license tier solely because of merge trains is rarely economically sensible unless other premium features, such as advanced code owner rules or epics, are already needed. In such cases, simpler alternatives are often sufficient, such as a team agreement to stagger merge requests over time, or a stricter requirement to rebase the feature branch against the current target branch immediately before merging and rerun the pipeline.
8. Alternatives and intermediate steps
For teams that shy away from the full merge train mechanism but still want to address semantic merge conflicts, a simpler intermediate step is available: merged results pipelines without the actual train queue already test every individual merge request against a simulated merge state, without the additional sequencing of several concurrent merge requests. This intermediate step reduces the risk of merge conflicts arising from the target branch itself, but still does not cover conflicts between two merge requests running at the same time.
Another pragmatic alternative is an organizational rule under which merge requests touching particularly sensitive code areas, such as database migrations or central configuration files, are merged manually one after another, while the rest of the codebase relies on the normal, parallel merge request pipeline process without a merge train. This selective application limits the wait-time overhead to exactly the areas where semantic merge conflicts are actually most likely and most expensive, instead of routing every merge request through the train queue indiscriminately.
9. Conclusion: merge trains as a targeted tool, not a default setting
Merge trains solve a real problem, namely semantic merge conflicts between concurrently merged changes on heavily used protected branches, and deliver a more traceable, semi-linear git history as a side effect. But the benefit depends directly on two factors: an already stable and fast pipeline, and an actually high merge frequency with several active contributors. Without these prerequisites, the mechanism mainly produces extra wait time and complexity without a corresponding payoff.
The table below summarizes the key decision criteria for or against merge trains as a practical checklist.
| Criterion | Merge trains pay off | Merge trains tend not to pay off | Note |
|---|---|---|---|
| Merge frequency on target branch | several times a day, several contributors | rare, roughly one merge a day or less | low frequency already lowers conflict risk |
| Pipeline runtime | a few minutes up to about 15 minutes | over 20 minutes | long pipelines lead to long queues |
| Test stability | reliable, hardly any flaky tests | unstable, frequently flaky suite | instability compounds through the train queue |
| GitLab license tier | Premium or Ultimate already in place | only free tier used | upgrading solely for merge trains rarely pays off |
| History of broken target branches | repeated semantic merge conflicts | never experienced | a concrete pain point is the best decision signal |
Mironsoft
CI/CD pipelines, zero-downtime deployments and release automation
Deployments that run without downtime and without the nail-biting?
We review existing GitLab pipelines for fragile deployment steps and missing safeguards, then build a release process with zero-downtime deployments, automated checks and a rollback you can actually trust in an emergency.
Pipeline Review
Checking an existing .gitlab-ci.yml for fragility, missing stages and security gaps.
Zero-Downtime Deployment
Building symlink releases, health checks and rollback strategies for Magento stores.
CI/CD Automation
Connecting tests, security scans and deployments into one reliable pipeline.
10. Summary
Merge trains: The essentials at a glance
Core idea of merge trains
Merge requests are tested sequentially against the expected state after all previous merges in the train, not against today's target branch.
Biggest benefit
Avoiding semantic merge conflicts at high merge frequency, plus a semi-linear, more traceable git history.
Most important prerequisite
An already stable, fast pipeline, since failures in the train trigger a recalculation for all subsequent merge requests.
When it tends not to help
Low merge frequency, long pipeline runtimes or unstable test suites usually do not justify the added effort.