What It Is
Stacked diffs (also called stacked PRs or stacked changes) is a code review workflow pattern where large changes are broken into a chain of small, dependent pull requests that build on each other sequentially. Instead of submitting one large PR with 1000+ lines, a developer creates a stack of 3-10 small PRs, each representing an atomic, self-contained change that can be reviewed and understood independently.
The pattern originates from Meta’s Phabricator and Google’s Critique code review systems, where per-change (not per-branch) review has been standard practice for over a decade. The challenge has been bringing this workflow to GitHub/GitLab-style branch-based review platforms that were not designed for it.
How It Works
- Developer creates a first change (e.g., database migration) and submits it for review
- Without waiting for review, developer creates a second change on top of the first (e.g., API endpoint using the new schema)
- This continues for subsequent dependent changes (e.g., frontend consuming the new API)
- Each change is reviewed independently by the appropriate specialist
- Changes land in order; if an earlier change needs revision, dependent changes are rebased
The critical operational challenge is rebasing: when a reviewer requests changes to diff 1, diffs 2-N must be recursively rebased. With vanilla Git, this means manual interactive rebasing with potential cascading merge conflicts. Specialized tooling (Graphite, ghstack, jj) automates this.
When to Use
- Large changes spanning multiple layers: Backend + API + frontend changes benefit from per-layer review
- Teams with review bottlenecks: When developers are blocked waiting for reviews, stacking keeps them productive
- Monorepos: Changes touching multiple modules benefit from atomic, sequential review
- High-throughput teams: Organizations shipping many changes per day need fast review cycles
When NOT to Use
- Small teams with fast review cycles: If reviews take <2 hours, the overhead of managing stacks may exceed the benefit
- Independent changes: If changes do not depend on each other, parallel non-stacked PRs are simpler
- Teams without tooling: Manual stacked diffs in Git are error-prone and time-consuming; do not attempt without Graphite, ghstack, jj, or similar tooling
- Junior-heavy teams: Stacking requires commit discipline and understanding of rebase mechanics
Evidence
Supporting:
- SmartBear study (2,500 reviews, 3.2M LOC): Review effectiveness drops sharply after 200-400 lines of code
- Google engineering productivity research: Teams with sub-24-hour review turnaround ship 2x faster
- Graphite reports (vendor-sponsored): Shopify 33% more PRs merged per developer; Asana engineers saved 7 hours/week
- DORA 2023 report: Improving code reviews can speed up delivery performance up to 50%
- Meta and Google have used per-change review internally for 10+ years
Challenging:
- Alex Jukes argues stacking “solves the problems of branching with more branching” and introduces significant complexity
- Pragmatic Engineer notes the pattern is most beneficial for large teams with monorepos; smaller teams may not see proportional gains
- The existence of multiple commercial tools (Graphite, Lubeno) built solely to manage stacking complexity is itself evidence of the pattern’s operational cost
- Cascading merge conflicts during rebase can negate velocity gains when earlier changes in the stack need significant revision
Tooling Landscape
| Tool | Type | Platform | Approach |
|---|---|---|---|
| Graphite | Commercial SaaS | GitHub | CLI + web UI on top of GitHub PRs |
| ghstack | Open-source | GitHub | CLI; commit-based stacking |
| spr | Open-source | GitHub | Single-commit PR management |
| git-town | Open-source | Any Git host | Branch synchronization CLI |
| Jujutsu (jj) | Open-source VCS | Any Git host | Native change-centric model with automatic rebase |
| Sapling | Open-source VCS | Any Git host | Meta’s VCS with native stacking |
| Lubeno | Commercial SaaS | Lubeno hosting | jj-native code hosting with stacked PRs |
| Gerrit | Open-source | Self-hosted | Google’s per-change review system |
| Phabricator | Open-source (archived) | Self-hosted | Meta’s original per-diff review system |
Related Patterns
- Trunk-based development: Alternative approach emphasizing short-lived branches and frequent merges to main. Can be combined with stacking or used instead of it.
- Ship/Show/Ask: Categorizes changes by review need. Stacking complements “Show” and “Ask” categories.
- Continuous Integration (original definition): Martin Fowler’s CI emphasizes integrating to mainline frequently, which stacking enables by making changes small enough to land quickly.