Essay - Published: 2025.08.01 | atomic-commits | build | create | creation-cycle | git | productivity | software-engineer | stacked-commits |
DISCLOSURE: If you buy through affiliate links, I may earn a small commission. (disclosures)
I've been using stacked / atomic commits for years - they're the default paradigm of version control at Instagram / Meta and I've found them to be extremely useful across orgs and projects.
I've also been playing around with AI agents lately and believe stacked commits are an excellent way to implement AI checkpointing.
In this post we're going to talk about what stacked commits are and why you should use them in your own workflows.
Before we can talk about what stacked / atomic commits are, we need to understand what the default version control paradigm is.
Today git is the leading version control technology for software. It uses commits to checkpoint work and branches to enable different working copies of the codebase to be worked on at the same time which can then be merged together later.

This led to the rise of "feature branches" as the primary paradigm for creating changes to the codebase.
This works but has a few challenges:

Let's use an analogy where our codebase is a skyscraper. Let's say we want to add a pool to the roof - that's our feature. In order to do this we probably need to change multiple things (idk I'm not a pool expert):
A feature branch is like trying to do this all at once. We build all the pieces and try to install them all at the same time (you can do this in software, harder to do in real world). But if there's another change happening at the same time - could be with the roof or the plumbing or just happens to touch the same spots - then these changes would collide and we get a merge conflict, holding up our project and whatever other projects are in conflict.
Or perhaps you submit your big change for review and someone says hey that plumbing is not right, now you may need to change your whole feature possibly wasting hours or days of work. And while you're doing that more changes are getting made to the building leading to potentially more merge conflicts.
In some ways this style of building is akin to the waterfall approach - build everything upfront then try to launch the whole thing all at once when it's finished.
Where traditional feature branches use branches as the unit of change, stacked commits use commits as the unit of change.

Stacked commits are a series of atomic commits. An atomic commit is a single logical change - not a "physical" one like a line of code or character but a logical one like a functional change to the system.
We still build our feature with a stack of commits but each commit is self contained and can be landed before the rest of the stack is complete.
An atomic commit could be:
But it is typically not all of these things together as these are usually distinct logical changes (though edge cases do exist so use your judgement).
The benefits of using atomic commits stem from the smaller surface area of change in each one:
One of the reasons stacked commits are preferred to feature branches at Meta is that there is so much code / so many systems, it's impossible for any one person to understand all of it. This means it's possible any small change might break everything - perhaps by increasing the cost of a hot path by ~2% or breaking 0.1% of traffic being sent from old clients. By splitting up each change, it's easier to tell WHAT small change broke so you can understand, revert, and fix it. If this was shipped together as part of a 6k loc change, we could still revert it (when in doubt, hit revert) but it may take longer to figure out what root cause is so we can prevent it from happening again.

Let's go back to our skyscraper analogy where we're trying to add a pool on the roof. Instead of building everything and trying to ship it at the end of the build cycle, we split up our build into phases and ship each one as it's ready:
We end up with the same feature overall but now our work is isolated to a single part of the building at one time. this allows us to launch in phases and limits the surface area of collisions with other work that may be happening at the same time.
Plus if we get review feedback that our approach is bad, we just have to scratch the part of the stack we've built so far / that's related to it - not the full feature cause we haven't built it yet!
In many ways this approach is less like waterfall and more like agile (lowercase a) - we are building milestones and shipping them to customers as soon as they're ready which means we get early feedback and can course correct with limited wasted cycles.
If we squint, we see that stacked commits and feature branches look very similar. The difference is that stacked commits are made of atomic commits that are constructed to be independently deployable whereas a feature branch is made up of many commits that are each partial changesets meaning we can't deploy a complete change until the end of the branch.
Here's the process I use to build stacks of atomic commits:
(Note: parallelization is possible though it's typically best to start out with a linear changeset then split the parallel parts when they're next up for review / land.)
I find this task breakup typically takes the form of:
By breaking it up this way you'll start to see natural patterns for breaking up features:
I will typically batch a small stack of atomic commits together to ensure it's taking the form of something that makes sense / I'm happy with then submit those for review before working on the next batch.
There's definitely a balance between commits that are too small for reviewers to understand the context / what you're building so they can't give good reviews and commits that are too large that mix logical concerns and are harder to review / have a higher likelihood of bugs. Finding that balance is an art but you'll start to build that muscle as you try it out.

In general you don't need any special tools to start stacking commits. In git, these stacked commits are represented by a series of branches that each contain a single commit.
That said it's not a first class citizen in git so may be a bit clunky. There are some tools that make this a lot nicer.
Graphite is my current choice. It is a CLI tool but also has a nice VS Code extension for those that like GUIs (I am a shameless Git GUI enjoyer). It's the closest to Meta's Smartlog (their internal stacked commit technology) I've found in the real world.
But there are several others I've heard of / taken a look at that people seem to like:
Pick one you like and try it out.
I've found atomic commits make the software dev cycle much smoother and more deterministic. Each change gets its own commit and review so we always know what's landing and each change is thoroughly discussed and considered.
It does take a bit to get used to and feels a bit manual at first but I find it's a bit more work upfront for a smoother dev cycle overall.
If you liked this post you might also like:
The best way to support my work is to like / comment / share for the algorithm and subscribe for future updates.