Trunk Based Development vs Gitflow: Which One Should Your Team Use
by Arif Ikhsanudin, Backend Developer
The Actual Question Behind the Debate
Your team is arguing about branching strategy. Half the developers want to adopt Gitflow because it looks organized. The other half want trunk-based development because they've read about Google doing it. Both sides are arguing about the mechanism without first answering the underlying question: what does your release model look like?
Branching strategies are release coordination mechanisms. The right one is determined by how you ship software, not by what's fashionable or what the organization you admire uses.
What Gitflow Actually Is
Gitflow, formalized by Vincent Driessen in 2010, is a branching model designed for software with scheduled releases — specifically software where multiple versions need to be maintained simultaneously. It defines these long-lived branches:
main— production-ready code, tagged at every releasedevelop— integration branch, where features merge before releaserelease/x.y— release preparation branch, branched from develophotfix/— branches off main for urgent production fixes
main ─────●─────────────────────────●──────
\ /
develop ──────●──────●──────●───────●────────
| | | /
feature ──────●──────● | /
| | /
feature ●──────● /
| /
release ●─●
This model makes sense if you're shipping a mobile SDK, a desktop application, or an on-premises enterprise product where customers run version 2.3 while you're building 2.4 and you still need to patch security vulnerabilities in 2.3. Gitflow gives you the branch structure to do that without your version 2.4 work contaminating a 2.3 hotfix.
The problems with Gitflow at most companies: the develop branch becomes a perpetual integration problem. Features wait in develop for the next release cycle. Merging feature branches into develop creates conflicts that multiply as features age. Release branches drift from develop. The model requires discipline to maintain and adds overhead that isn't justified if you don't have the multi-version maintenance problem it was designed to solve.
What Trunk-Based Development Actually Is
Trunk-based development (TBD) means everyone integrates to a single branch (called main or trunk) frequently — typically at least once per day. Short-lived feature branches (one to two days maximum) merge to main via PR. No long-lived integration branches. Releases are cut from main, tagged, and deployed.
main ──●──●──●──●──●──●──●──●──(tag v1.2.3)──●──●──
| | | |
feat ──●──● | ──●──● |
| |
feat ──●──●──────●
TBD requires feature flags (sometimes called feature toggles) for work that isn't ready to be visible to users but is ready to be in production. You merge the code behind a flag, deploy it, and enable it when it's ready. LaunchDarkly and Unleash are common feature flag services; you can also implement a basic version in-house with a database table.
// Feature flag check — code is deployed but not yet user-visible
if (featureFlags.isEnabled("new_payment_flow", user)) {
return newPaymentFlowService.process(order);
} else {
return legacyPaymentFlowService.process(order);
}
The constraint TBD imposes: every commit to main must leave the codebase in a deployable state. This requires robust CI. If a failing test on main is treated as a known issue rather than a blocker, TBD doesn't work — you'll be shipping broken code constantly.
The Decision Framework
Use Gitflow when:
- You ship versioned artifacts — libraries, mobile apps, packaged software
- You maintain multiple major versions simultaneously
- Your customers control their own upgrade schedule (enterprise on-premises deployments)
- Release cycles are measured in weeks to months
Use trunk-based development when:
- You ship a web service or SaaS product
- You deploy to production multiple times per week (or per day)
- You can gate unfinished features behind flags
- You have a solid CI pipeline that catches regressions before they merge
Most companies building SaaS products should be on TBD. Most teams shipping mobile SDK releases or enterprise packaged software should be on Gitflow or a simplified variant.
The Simplified Middle Ground
A lot of teams don't need the full weight of either model. A simplified Gitflow:
main= production- Short-lived feature branches merge to main via PR
- Releases tagged from main
- Hotfixes branch from the release tag, merged back to main and tagged
No develop branch. No release branches unless you need to support multiple versions. This gives you the release tagging discipline of Gitflow without the integration branch overhead, and most of the integration speed of TBD.
What Goes Wrong When You Pick the Wrong One
A SaaS team on Gitflow typically develops a permanent integration problem. The develop branch gets into a broken state that nobody owns fixing. Features queue up waiting for "the next release." Releases become big-bang events instead of small, routine deployments. Defects that would have been caught in daily production exposure instead age for two weeks in develop.
A library team on TBD typically ships half-complete features to public consumers. A migration that takes three commits to complete gets merged incrementally to main, and an external developer picking up version 1.4.2 between commits one and three gets a broken build. Feature flags don't solve this for SDK consumers — they're not running your server.
Pick the one that matches how you actually ship, not the one that sounds more sophisticated.