Trunk-Based Development, Practically
Introduction¶
Trunk-based development (TBD) means everyone integrates into one branch
(main / trunk) frequently — at least daily — with branches living hours to a
couple of days, not weeks. It's the workflow behind continuous delivery.
Why not long-lived branches¶
GitFlow's develop + release/* + feature/* + hotfix/* model creates:
- Merge hell — a two-week feature branch diverges far from main; the merge is a high-risk event.
- Delayed integration — bugs from the interaction of two features aren't found until both merge.
- Stale branches — half-finished work rotting for months.
TBD trades this for the discipline of keeping every change small and the trunk always releasable.
How features that take weeks fit¶
You don't hold the code out of trunk — you hide it:
- Feature flags — merge incomplete code behind an
if flag("new-checkout")that's off in production. Turn it on when ready, for a percentage, per customer. Remove the flag once stable. - Branch by abstraction — introduce an interface, add the new implementation behind it, switch, delete the old — each step a small merged PR.
- Keep migrations backward compatible (expand/contract) so a half-migrated schema still works.
if features.enabled("new-pricing", user=request.user):
price = new_pricing_engine(cart)
else:
price = legacy_pricing(cart)
Keeping trunk releasable¶
- Required CI checks on the PR: build, unit + integration tests, lint, security scan. Red trunk blocks everyone — fix-forward or revert within minutes.
- Branch protection: no direct pushes to
main, require PR + 1 review + green checks, require branch up to date before merge (or use a merge queue). - Merge queue (GitHub/GitLab): serialises merges, re-runs CI on the combined result, so "green PR + green PR = red main" can't happen.
- Small PRs. A 200-line PR gets a real review in 10 minutes; a 2,000-line one gets a rubber stamp. Small PRs are the core enabling habit.
Releasing¶
- Release from trunk — tag a commit, deploy it. Every commit is a release candidate.
- If you need a stabilisation window, cut a short-lived
release/1.4branch, cherry-pick only fixes onto it, delete it after the release. Days, not weeks. - Hotfix = a normal small PR to trunk, then cherry-pick to the active release branch if one exists.
Verification and troubleshooting¶
git log --oneline origin/main | head # steady stream of small commits?
git branch -r --sort=-committerdate | head # any branches older than a few days?
- Trunk keeps breaking — PRs merging without the branch being up to date, or flaky tests being ignored. Add "require up to date" / a merge queue; quarantine flaky tests aggressively.
- Feature flags pile up — no removal discipline. Track flags with an expiry; a stale flag is tech debt and a config-explosion risk. Review quarterly.
- Long branches creep back — usually a too-big feature with no decomposition plan. Require a "how will this be split" note before starting.
- Reviews are a bottleneck — PRs too big, or too few reviewers. Smaller PRs, and pair on the tricky ones instead of async review.
- "We can't test everything on every PR, it's too slow" — parallelise, cache (see GitHub Actions cache strategies), split into a fast required set + a slower post-merge set.
- Rollback is scary — if trunk is always releasable and deploys are small, rollback is just deploying the previous tag. If it's scary, deploys are too big.
Related tools and reading¶
- On-site: Uptime / status check.
- Related posts: Git rebase vs merge, Blue-green vs canary deployments.
Stuck on something this site can't fix?Reach out to Prabath directly on LinkedIn.More in DevOps & CI/CD
OpenTelemetry for Distributed Tracing
A trace follows one request across services. OpenTelemetry is the vendor-neutral way to produce them — here's the model, the Collector, and sampling that won't bankrupt you.
October 24, 2026pre-commit Hooks That Actually Help
pre-commit runs checks before a commit lands, catching formatting, secrets, and syntax errors locally. Here's a config that helps without being annoying.
October 24, 2026Chaos Engineering Basics
Chaos engineering is controlled experiments that inject failure to verify your system tolerates it. Here's the method, safe blast radius, starter experiments, and game days.
October 24, 2026