Should you build your own merge queue?
A merge queue is a weekend prototype and a multi-year maintenance commitment. Here's how to tell which one you're actually signing up for, and the operating tail that decides it.
A basic merge queue is genuinely easy to build. Take the PRs in order, rebase each on the ones ahead of it, run CI, merge if green. You can have that working in a weekend, and with an LLM, in an afternoon.
So the honest answer to “should you build your own?” is: sometimes. Here’s how to tell.
When building your own is fine
If your repository is small, your merge volume is low, and a broken main is a minor inconvenience you can fix in minutes, build it. A serial queue that rebases and runs CI is a reasonable amount of code, and you’ll understand every line. Don’t pay a vendor for plumbing you can own outright at no real cost.
The afternoon version works right up until two things happen at once: volume climbs, and the cost of being wrong climbs with it.
The operating tail
Here’s what the prototype doesn’t include, and what you sign up to own the day you ship it.
Batching and parallelism. A serial queue tests one PR at a time, so as the team grows the queue itself becomes the bottleneck. To keep merges flowing you need to test several PRs at once, speculatively, as if the ones ahead of them will pass. That’s a different and much harder system than the serial prototype, and it’s the feature that makes a queue worth having at scale in the first place.
Bisection. The moment you batch, you inherit a new problem: when a batch goes red, which PR broke it? A naive queue throws away the whole batch and retries, punishing the innocent PRs. A good one isolates the culprit and lets the rest through. Building that well is most of the work.
Flaky tests. One flaky test will stall the entire train, repeatedly, and your queue has no idea the failure was noise. Detecting and quarantining flakes is its own project. (We wrote a lot about this.)
Priorities. Not every PR is equal. A production hotfix needs to jump the line; a release branch needs to drain before a freeze; a routine dependency bump can wait. The moment a queue exists, people want to control its order, and a priority scheme that’s predictable and still doesn’t starve the low-priority PRs is its own design problem.
The integrity invariant. The commit you tested has to be the commit you land. Same bytes. The obvious implementation reconstructs the merge commit at land time, which produces a different commit than the one CI signed off on. That drift is silent. Branch protection doesn’t catch it, because branch protection ran on the tested commit. GitHub’s own merge queue shipped exactly this bug and corrupted merges for four and a half hours. We cared enough about this class of failure to formally verify our core algorithm with TLA+.
Monitoring and capacity. Someone has to watch the queue, alert when it wedges, and keep it sized to your merge volume as the team grows. A queue nobody is watching fails silently, which for a merge queue is the worst way to fail.
Surviving GitHub itself. Your queue runs on top of GitHub’s API, and GitHub has outages, rate limits, and webhooks that arrive late or never. Each one becomes your queue’s problem to detect, back off from, and recover from without dropping a PR or merging one twice.
And the list goes on. Freezes and deployment windows. Cross-repo dependencies. CI cost, which is mostly won or lost in the queue. Reporting and audit trails. Every item is a feature your team now maintains instead of shipping your actual product.
Build is a line item. Run is a payroll line.
It’s tempting to price a merge queue as a one-time build: a few weeks of work, then it’s done. It is never done.
Building it is a line item you pay once. Running it is a payroll line you pay every month, because every item in that operating tail is somebody’s ongoing job. The prototype is the cheapest moment in the tool’s entire life. From the day it touches main, the cost is maintenance, on-call, and the new pieces you keep bolting on as your scale outgrows the version you shipped.
This is the mistake the afternoon prototype encourages. It shows you the build cost, which is now near zero, and hides the run cost, which didn’t move. You decide based on the number you can see.
Doing the ROI honestly
Put rough numbers on it, for your own team.
The serial prototype is maybe two or three weeks. A queue that survives the operating tail above is closer to a strong infrastructure engineer for a quarter to get right, then a standing slice of an engineer, call it 10 to 20 percent, forever to keep healthy, and more during the incidents. On a loaded platform-engineering salary, that recurring slice alone runs into six figures a year. Then add the opportunity cost, which is the real one: that’s your most senior infrastructure person spending their time on a problem every scaling team has already solved, instead of shipping features your customers actually asked for.
Against that, the buy side is a subscription plus an afternoon of setup, with the entire operating tail owned by someone whose only product is the queue. You also get it working today, not a quarter from now, which matters more than it looks, because teams only go looking for a merge queue once the pain is already here.
The build case wins when the tool is small and the stakes are low. It stops winning the moment the tail shows up, because the tail was the thing you were comparing against all along.
The reason that isn’t in the business case
Here’s what the ROI math misses: a lot of “build” decisions aren’t made on ROI at all.
Building your own merge queue is fun. It’s yours, you understand every line, and with an LLM you can have a working one by the afternoon and feel great about it. Those are real reasons, and none of them show up in the spreadsheet. What shows up in the spreadsheet is the justification written afterward, once the decision is already made.
There’s nothing wrong with building something because you want to. Just be honest about which one it is. If the queue is genuinely core to your business, or small enough to own outright, build it. If you’re building it because it’s more interesting than the roadmap, that’s a fine reason to spend a weekend and an expensive reason to take on a standing system that competes with your actual product for years.
The tell is what happens after the fun part ends. The prototype ships, the novelty wears off, and the operating tail is still there every month, whether or not anyone still enjoys it.
The real question
It isn’t “can we build a merge queue.” You can. It’s “do we want to own a merge queue as a standing system, forever, including the night it wedges and the day it silently lands the wrong commit.”
For a small repo, that ownership is cheap and worth it. At scale, you’re not maintaining a weekend script anymore. You’re running critical infrastructure whose failure mode is a corrupted main that nobody notices, and that work competes with the product only you can build.
That’s the line. Below it, build. Above it, the bill was always the tail, and the tail is yours the moment you ship.
That tail is the part we took off teams’ hands. We make a merge queue, so you don’t have to keep one alive.

