The problem: trains couldn’t scale
Back in 2016, GitHub’s largest monorepo was absorbing nearly 1,000 pull requests per month. As the platform grew in both services and shipping frequency, the engineering team needed a way to batch multiple pull requests together for testing, deployment, and merging. The solution at the time was trains—special pull requests that grouped multiple changes (passengers) under a designated conductor who managed deployment and conflict resolution.
Trains initially improved throughput, but they soon became a bottleneck. A typical train could carry up to 15 pull requests, and when a single deployment issue, conflict, or removal request derailed a train, everyone aboard waited. Developers sometimes spent 8+ hours in a queue only to see their change pulled at the last minute due to a conflict between two other pull requests. Internal developer surveys consistently ranked deployment as the most painful part of the daily workflow, and quantitative metrics showed a steady climb in time-to-merge.
The pain wasn’t uniform either. Trains were only used on the biggest monorepo, so engineers moving between teams or contributing to unfamiliar services faced wildly different processes. GitHub’s inner source culture made that friction especially costly.
Designing merge queue from the ground up
By 2020, GitHub engineers agreed the internal tooling had to go. The replacement needed to meet three goals:
- Simplify the developer’s intent. Engineers wanted to express two things—“I want to ship this” and “I’m moving on to other work”—and let the system handle the mechanics.
- Isolate bad actors. A pull request causing conflicts or build failures should not stall every other change waiting to merge. Throughput of the whole system mattered more than fairness to any single pull request.
- Automate consistently. The same process should apply across services and repositories, eliminating manual toil and special-case logic.
Merge queue started as an internal project but was built with an eye toward eventual customer availability. Rollout was deliberately incremental. The team couldn’t take the deployment pipeline offline for days, so every phase had to keep a working system in place. At most, they could block deployments for an hour or so for a test or migration. They also had to retrain roughly 1,000 engineers spread across time zones, which meant phased rollouts, early-morning trials, and occasional rollbacks before the wider developer population started work.
How GitHub uses merge queue today
Merge queue is now the single entry point for shipping code changes at GitHub. Before the feature was made generally available, it had already processed more than 30,000 pull requests and 4.5 million CI runs for GitHub.com.
The mechanics are built into the pull request workflow. Merge queue dynamically groups candidate pull requests, kicks off builds and tests via GitHub Actions, and enforces branch protection so the main branch is never updated to a failing commit. Conflicting pull requests are automatically detected and removed, and the queue re-forms groups as needed. No special ChatOps commands, labels, or comment syntax are required.
That integration pays off in developer experience. A developer can add a pull request to the queue with one click and remove it just as easily if they spot a problem. The system also lifted the old ceiling on batch size—trains maxed out at 15 changes per deployment, while merge queue can safely handle 30 or more.
The numbers reflect the shift. Every month, over 500 engineers merge 2,500 pull requests into the large monorepo—more than double the volume from a few years ago. Average wait time to ship a change has dropped by 33%. Anecdotal feedback matches the metrics: one engineer called merge queue “one of the best quality-of-life improvements to shipping changes that I’ve seen a GitHub!”
Getting started
Merge queue is available for public repositories on GitHub.com owned by organizations, and for all repositories on GitHub Enterprise (Cloud or Server). For details on configuration and best practices, see GitHub’s announcement on merge queue general availability.



