Trunk-Based Development — Ship Faster With Short-Lived Branches
The problem with long-lived branches#
You create a feature branch. Two weeks later you try to merge. 47 conflicts. Three days of integration work. Tests break. You fix them. Another developer merged while you were fixing. More conflicts.
Long-lived branches are where productivity goes to die.
What is trunk-based development#
Every developer commits to a single shared branch — trunk (usually main). Branches exist, but they live for hours, not weeks.
The rules are simple:
- Branches last less than a day — ideally less than a few hours
- Merge to trunk constantly — multiple times per day
- Trunk is always releasable — every commit passes CI
- Feature flags control rollout — not branches
Short-lived branches in practice#
A typical workflow looks like this:
- Pull latest trunk
- Create a branch (
feat/add-retry-logic) - Make a small, focused change
- Open a PR — it touches 50–200 lines, not 2,000
- Get a quick review (small PRs get fast reviews)
- Merge to trunk
- Branch is deleted
The entire cycle takes hours, not days. The branch never has time to diverge significantly from trunk.
Why feature flags beat feature branches#
Long-lived feature branches exist because teams want to hide incomplete work. Feature flags solve this better:
# Instead of a long-lived branch, merge incomplete code behind a flag
if feature_flags.is_enabled("new-checkout-flow", user_id=user.id):
return new_checkout(cart)
else:
return legacy_checkout(cart)
Benefits over branches:
- No merge conflicts — code is in trunk from day one
- Incremental integration — each piece is tested with the real codebase
- Targeted rollout — enable for 1% of users, then 10%, then 100%
- Instant rollback — flip the flag, no deployment needed
- A/B testing built in — compare old vs. new with real traffic
Continuous integration is non-negotiable#
Trunk-based development without CI is chaos. Every commit to trunk must:
- Compile and build — broken builds block everyone
- Pass unit tests — fast feedback, under 5 minutes
- Pass integration tests — catch cross-service issues
- Pass linting and formatting — no style debates in PRs
- Run security scans — catch vulnerabilities early
If CI takes 45 minutes, trunk-based development will fail. Invest in fast pipelines:
- Parallelize test suites
- Use incremental builds
- Cache dependencies aggressively
- Run only affected tests on each commit
Releasing from trunk#
In trunk-based development, every commit to trunk is a release candidate. Two common release strategies:
Release on every commit#
Every merge to trunk triggers deployment. This is what Google, Meta, and Netflix do at scale. It requires:
- Robust CI/CD pipelines
- Feature flags for incomplete work
- Automated rollback on error spikes
- Canary deployments or blue-green deploys
Release on a schedule#
Tag trunk at regular intervals (daily, weekly). Less aggressive but still benefits from small, frequent merges.
# GitHub Actions — deploy on every trunk merge
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm test
- run: npm run build
- run: ./deploy.sh --canary
- run: ./deploy.sh --promote # after canary passes
CI/CD pipeline integration#
A trunk-based CI/CD pipeline has distinct stages:
Pre-merge (PR checks)#
- Lint, type-check, unit tests
- Preview environment for visual review
- Automated PR size warnings (flag PRs over 400 lines)
Post-merge (trunk)#
- Full integration test suite
- Build artifacts and container images
- Deploy to staging automatically
- Run smoke tests against staging
Release#
- Canary deployment (5% traffic)
- Monitor error rates and latency
- Gradual rollout (25% → 50% → 100%)
- Automated rollback if metrics degrade
How Google does it#
Google has operated on a single trunk (the monorepo) for over 20 years:
- 86 TB of source code in one repository
- Thousands of commits per day to trunk
- No long-lived branches — everything merges to head
- Automated testing catches breakages within minutes
- Code review is mandatory — but PRs are small and fast
- Feature flags everywhere — incomplete features ship constantly
The result: Google ships changes to production thousands of times per day.
How Meta does it#
Meta follows a similar philosophy:
- Trunk-based with short-lived branches — typically merged same day
- Gatekeeper system for feature flags — controls rollout to billions of users
- Continuous push to production — multiple times daily
- Automated regression detection — ML-based anomaly detection on metrics
- Diff stacking — developers stack small dependent changes for review
Common objections (and answers)#
"But what about big features?"#
Break them into small, independently mergeable pieces. Use feature flags to hide incomplete UI. Build the backend first, then the frontend. Ship 20 small PRs, not one massive one.
"What if someone breaks trunk?"#
That is what CI is for. Fast tests catch breakages before merge. If something slips through, revert immediately. A 50-line change is easy to revert. A 2,000-line change is not.
"We need code review"#
Trunk-based development does not mean skipping review. It means reviewing small changes quickly. A 100-line PR gets reviewed in 15 minutes. A 2,000-line PR sits for days.
"Our tests are too slow"#
Fix that first. Trunk-based development exposes slow CI as the bottleneck it always was. Parallelize tests, use test sharding, cache aggressively.
Migration path#
Moving from GitFlow or long-lived branches to trunk-based development:
- Shorten branch lifetimes — set a 2-day maximum, then reduce to 1 day
- Speed up CI — target under 10 minutes for the PR pipeline
- Introduce feature flags — start with one service, prove the pattern
- Reduce PR size — set soft limits (300 lines), then hard limits
- Automate deployments — remove manual gates where possible
- Monitor trunk health — dashboard showing build status, test coverage, deploy frequency
Key takeaways#
- Short-lived branches (hours, not weeks) eliminate merge conflicts and integration pain
- Feature flags decouple deployment from release — ship code without exposing it
- Fast CI is the foundation — if your pipeline is slow, fix that first
- Small PRs get fast reviews — 100 lines reviewed in minutes, not days
- Google and Meta prove it scales — trunk-based works for the largest codebases on earth
- Trunk is always releasable — every commit is a potential production release
Visualize your branching strategy#
Map out your trunk-based workflow, CI/CD pipeline, and feature flag architecture — try Codelit to generate an interactive diagram.
Article #357 of the Codelit system design series. Explore all articles at codelit.io.
Try it on Codelit
GitHub Integration
Paste a repo URL and generate architecture from your actual codebase
Related articles
Try these templates
GitHub-like CI/CD Pipeline
Continuous integration and deployment system with parallel jobs, artifact caching, and environment management.
9 componentsCI/CD Pipeline Architecture
End-to-end continuous integration and deployment with testing, security scanning, staging, and production rollout.
10 componentsMicroservices with API Gateway
Microservices architecture with API gateway, service discovery, circuit breakers, and distributed tracing.
10 componentsBuild this architecture
Generate an interactive architecture for Trunk in seconds.
Try it in Codelit →
Comments