shipcodefast.com

Trunk-Based Development: Shipping in Small Batches

5 min read

Trunk-based development is a branching strategy with one simple rule at its center: everyone integrates into one shared branch, frequently, in small pieces. It sounds like a minor process choice, but it changes how a team splits work, reviews code and releases software. This guide covers what the practice actually requires, what the research says, and the situations where a different model is the better call.

What trunk-based development means

DORA, a research program that studies software delivery performance, defines it this way on its trunk-based development capability page: each developer divides their work into small batches and merges that work into trunk at least once, and potentially several times, a day. In many repositories, trunk is the branch called main.

That definition does not ban branches or pull requests. It bans long-lived ones. The guidance on short-lived feature branches from trunkbaseddevelopment.com is specific: a branch should last a couple of days at most, because past two days it risks turning into a long-lived feature branch, and it should have one developer on it, or two if they are pairing.

So the day-to-day workflow looks like this:

  1. Pull the latest main and create a branch for one small change.
  2. Make the change with its tests, and open a pull request the same day.
  3. Get it reviewed quickly, merge it, and delete the branch.
  4. Start the next small change from the updated main.

What the DORA research found

DORA's page reports that its analysis of 2016 and 2017 data found teams achieve higher software delivery and operational performance, meaning delivery speed, stability and availability, when they follow three practices:

  • three or fewer active branches in the application's code repository
  • merging branches to trunk at least once a day
  • no code freezes and no integration phases

DORA also treats trunk-based development as a required practice for continuous integration, which it describes as trunk-based development combined with a suite of fast automated tests that run after each commit to trunk. Those findings describe what higher-performing teams tend to do. They are not a guarantee that changing your branching model alone will speed anything up, but they are a strong signal about which habits travel together on teams that ship well.

Make the batches small

Trunk-based development only works if the work is cut into pieces small enough to merge daily. That is the hard part, and it is a skill teams have to practice.

DORA's page on working in small batches gives a blunt test: any batch of work that takes longer than a week to complete and check in is too big. It suggests aiming for pieces that take hours to a couple of days.

Size in lines matters too. Google's public code review guide on small changes says that 100 lines is usually a reasonable size for a change and 1,000 lines is usually too large. It lists why small changes win: they are reviewed more quickly and more thoroughly, are less likely to introduce bugs, are easier to merge, and are simpler to roll back.

Some practical ways to split a feature:

  • Land the plumbing first. A new database column, an interface, or a function with no callers yet can be reviewed and merged on its own.
  • Separate refactoring from behavior changes. Renaming and moving code in one pull request, then changing logic in the next, makes both easier to review.
  • Build the entry point last. Martin Fowler's article on branching patterns describes hiding a partially built feature by hooking up the keystone interface, such as the button or route that exposes it, at the very end. Until then, the new code is merged but unreachable.
  • Use a flag when there is no natural keystone. Fowler notes that if there is no easy way to hide a partial feature, feature flags can do it.

Keep code review fast

Slow review can quietly undo trunk-based development. DORA lists an overly heavy code review process as a common pitfall: when review takes hours or days, developers stop working in small batches and bundle many changes together, reviewers then put off the large reviews, and the cycle feeds itself.

DORA's recommendation is synchronous review: when a change is ready, ask a teammate to review it right then, rather than filing a request and starting something new. It also notes that if a team pair programs, the code has already been reviewed by a second person. Google's guide on review speed sets an outer limit: one business day is the maximum time it should take to respond to a review request.

Small changes make fast review possible, and fast review makes small changes worth the effort. A team agreement like "review requests get a response before your next task" does more for trunk-based development than any tooling.

Keep main releasable

If everyone merges into main daily, main has to stay healthy all the time. Three habits do most of the work:

  • Test before you merge. DORA names not running automated tests before committing as another pitfall, and suggests protecting the branch so that pull requests can only merge when all tests have passed.
  • Fix or revert in minutes. In DORA's description of continuous integration, when the build fails, developers stop and either fix it right away or revert the change if it cannot be fixed within a few minutes. Reverting is not a failure. It is the fastest way to give everyone a working trunk back.
  • Drop code freezes. A freeze is a sign that main is not trusted to be releasable. The DORA findings list no freezes and no integration phases among the practices of higher-performing teams.

When it does not fit

Trunk-based development is not the right answer for every project, and pretending otherwise leads to frustration.

  • Open-source projects with outside contributors. Fowler points out that open-source projects commonly have a few trusted maintainers and many untrusted contributors, and a maintainer usually does not know the contributors or the quality of their code. In that setting, pre-integration review and feature branches make a great deal of sense. He adds that some commercial teams have a similar structure, and the same logic applies to them.

  • Teams without automated tests. Merging daily into a branch with no reliable test suite just moves breakage into main faster. DORA frames fast automated tests as part of continuous integration itself. Build that safety net first, starting with the code that changes most.

  • Teams in the middle of a transition. Going from month-long branches to daily merges in one step is a big jump for any team. Shrink the branch lifetime gradually and measure as you go.

How to start

DORA suggests measuring a few things: the number of active branches, how often and how long code freezes happen, how often changes merge to trunk, and how long code review approval takes. Pull those numbers from your repository today, before changing anything.

Then pick one rule the whole team can see and check, such as "no branch lives longer than two days." Track it for a month. The oldest open branch in your repository is the simplest early warning you have: when it starts getting older, batches are getting bigger, and that is the moment to split the work rather than wait for the merge.

More from shipcodefast.com