
Stacked PRs Are Just Big PRs With Extra Steps#
I love small PRs.
Seriously. I think breaking work into small, focused, independently reviewable changes is one of the best habits a software engineer can develop. Small PRs are easier to understand, easier to test, easier to review, and easier to merge.
Which is why I hate stacked PRs.
I know that sounds contradictory. Stacked PRs are supposed to give us all the benefits of small PRs without forcing developers to wait for each change to merge before starting the next one.
And I get the appeal. Nobody likes reviewing a 2,000-line PR. Nobody wants to sit around waiting for an approval before they can keep working.
But every time someone asks me to review a stack of five dependent PRs, I find myself wondering whether we’ve actually made the work easier to review, or whether we’ve just taken one giant PR, sliced it into pieces, and put a bow on it.
Because five small diffs are not the same thing as five small changes.
Small doesn’t mean understandable#
The advice to keep PRs small is good advice. I’m not arguing against it.
But somewhere along the way, I think we’ve started confusing small diffs with small changes.
They’re not the same thing.
A small change is something I can look at, understand, evaluate, and approve without needing to reconstruct an entire feature in my head. It has a clear purpose. It makes sense on its own. It does one thing.
A small diff is just a small number of changed lines.
You can absolutely have one without the other.
Even Google’s engineering guidelines on small changes make this distinction. The goal is a small, self-contained change. They specifically warn against making a change so small that its implications become difficult to understand. When introducing a new API, for example, they recommend including a usage so the reviewer can see how it’s actually meant to work.
That’s exactly the point.
If PR 1 introduces an abstraction, but I need to read PR 4 to understand why that abstraction exists, PR 1 isn’t independently reviewable in any meaningful sense.
It’s just incomplete context presented as a complete review.
There’s even some research that supports the distinction. A controlled experiment on decomposing code changes found real benefits to separating different concepts, including fewer incorrectly reported issues. But decomposition didn’t improve reviewers’ understanding of the change rationale or increase the number of defects they found. It also led to more context-seeking.
That study wasn’t specifically about stacked PRs, but the finding feels familiar.
Breaking something into smaller pieces doesn’t automatically make it easier to understand. Sometimes it just makes you work harder to find the pieces you need.
The author gets the benefits. I get the homework.#
Here’s what I think gets lost in most conversations about stacked PRs: the person writing the stack and the person reviewing it are having completely different experiences.
The author has all the context.
They know what they’re building. They know why the abstractions exist. They know what the next PR is going to do because they already wrote it.
To them, the stack is a neat sequence of logical steps.
To me, showing up cold to review it, it’s a scavenger hunt.
PR 1 introduces a new interface. I can’t tell whether it’s a good interface because nothing uses it yet.
PR 2 adds some supporting infrastructure.
PR 3 finally shows how the interface gets used. Now I have enough context to form an opinion about PR 1.
PR 4 changes the interface from PR 1 anyway.
PR 5 ties everything together, and suddenly the architecture makes sense.
Great. Now I want to go back and review PR 1 again.
And this is what drives me nuts about the whole experience. The stack didn’t make the change smaller. It just made me assemble it myself.
I’m not reviewing five independent changes. I’m reviewing one large change spread across five different places, each showing me a different part of the story.
Worse, I don’t always know whether the code I’m looking at is even the code that’s going to survive to the end of the stack.
Am I spending ten minutes thinking through an abstraction that gets rewritten two PRs later? Should I leave this comment now, or is it already addressed upstack? Do I need to read the whole stack before I can meaningfully approve the first layer?
The author already knows the answers.
I don’t.
And code review is supposed to be about more than verifying that each individual diff looks reasonable. I’m trying to understand whether the design makes sense, whether the pieces fit together, and whether the final behavior is correct.
Those questions don’t always fit neatly inside one layer of a stack.
Better navigation doesn’t fix missing context#
To GitHub’s credit, stacked PR support has improved considerably. Native stack navigation, automatic rebasing, and better handling of approvals are real improvements.
But they mostly make the mechanics of stacking less painful.
They don’t fundamentally change the problem I have as a reviewer.
In fact, GitHub’s own guidance for reviewing stacks recommends reading the stack from the top down to understand the context, then reviewing it from the bottom up.
Think about that for a second.
Before I can review the first PR, I’m supposed to read through the rest of the stack to understand what we’re building. Then I go back to the beginning and work through it in the opposite direction.
That’s not exactly selling me on the simplicity of the workflow.
And sure, better tooling can make that process less annoying. I would absolutely appreciate being able to see the entire final diff, jump between layers, and know when a line I’m reviewing gets changed later in the stack.
But navigation is not context.
Making it easier to click between five PRs doesn’t magically turn them into five independently understandable changes.
It just makes the scavenger hunt faster.
There’s also an increasingly relevant AI angle here. As coding agents make it easier to generate large amounts of code quickly, stacks are an attractive way to package that output into something that looks reviewable.
But generating code faster doesn’t make human attention any less valuable.
If anything, it makes the quality of the review experience more important.
We shouldn’t confuse making code easier to submit with making it easier to review.
I’d rather we actually made smaller changes#
My ideal workflow isn’t a giant PR.
It’s not a five-PR stack that collectively represents one giant PR, either.
It’s a series of genuinely small changes that can stand on their own.
Do the refactor first. Give it a clear purpose, review it, and merge it.
Add the new API with enough usage to understand whether the design works. Review it and merge it.
Build the next piece on top of something that’s already in the codebase.
That’s harder than just slicing a feature into a chain of dependent branches. It requires thinking about how to structure the work, where the boundaries are, and what can be useful independently.
But I think that’s worthwhile engineering work.
Of course, not every change can be broken up perfectly. Sometimes dependencies are unavoidable. Sometimes a stack genuinely is the most practical option. And I understand why authors like being able to keep moving while earlier work is under review.
I’m not saying stacks should never exist.
I’m saying we should stop treating them as though they’re automatically the best way to make large changes reviewable.
Because when the individual PRs don’t make sense without the rest of the stack, we haven’t solved the large-PR problem. We’ve just moved the complexity from the author to the reviewer.
I don’t need convincing that small PRs are good. I already believe that. I want more of them.
What I don’t want is to take a large change, cut it into five dependent pieces, and pretend we’ve made it five times easier to review.
I’d rather we do the harder work of finding changes that can actually stand on their own.
Maybe stacked PR tooling will eventually change my mind. Maybe one day someone will send me a stack, I’ll review it without getting annoyed, and I’ll finally understand what everyone loves about this workflow.
Until then, I’m not using them.
Five small diffs are not the same thing as five small changes.