From Beginner to Advanced: A Complete One-Stop Guide to Fast, Safe, Continuous Software Delivery
1. What is trunk-based development?
Trunk-based development, often shortened as TBD, is a source-control branching strategy where developers integrate small changes frequently into one shared main branch.
That shared branch is usually called:
main
master
trunk
mainline
Modern repositories usually call it main.
The core definition:
Trunk-based development is a branching model where developers collaborate around a single main branch and avoid long-lived development branches.
The trunk-based development reference site defines it as a source-control branching model where developers collaborate on code in a single branch called trunk and resist creating long-lived development branches by using supporting techniques.
2. The simplest mental model
Traditional branch-heavy model:
Work privately for days/weeks โ merge later โ suffer integration pain
Trunk-based model:
Integrate tiny changes continuously โ catch problems early โ keep main releasable
Code language: JavaScript (javascript)
In one line:
Trunk-based development makes integration continuous instead of occasional.
3. The big idea
The big idea is not โeveryone randomly pushes to main.โ
That is chaos, not trunk-based development.
The real idea is:
Everyone works close to main.
Changes are small.
CI is fast.
Main stays healthy.
Incomplete work is hidden with feature flags.
Production can be released or rolled back safely.
Code language: JavaScript (javascript)
flowchart TD
A[Small change] --> B[Short-lived branch or direct commit]
B --> C[Fast CI]
C --> D[Review or pair review]
D --> E[Merge to trunk/main]
E --> F[Build artifact]
F --> G[Deploy safely]
G --> H[Release with flag or rollout]
H --> I[Observe]
I --> J[Rollback or continue]
Code language: CSS (css)
AWS DevOps Guidance recommends trunk-based development paired with a pull-request workflow using short-lived feature branches as an effective DevOps branching strategy, mainly because it promotes continuous integration and helps teams discover integration problems earlier.
4. Why trunk-based development exists
Software teams often suffer from delayed integration.
Example:
Developer A works on feature branch for 2 weeks.
Developer B works on another branch for 2 weeks.
Developer C changes shared code.
QA starts late.
Merge conflicts explode.
Release becomes scary.
Trunk-based development attacks this problem directly.
It says:
Do not delay integration.
Make integration small, frequent, automated, and safe.
Code language: PHP (php)
5. The trunk
The trunk is the central branch.
Usually:
main
Sometimes:
trunk
master
mainline
Rules:
- Trunk must stay healthy.
- Trunk must be protected.
- Trunk must have fast feedback.
- Trunk must be releasable or close to releasable.
- Trunk must not become a dumping ground.
- Trunk should not contain uncontrolled broken work.
gitGraph
commit id: "A"
commit id: "B"
commit id: "C"
commit id: "D"
Code language: JavaScript (javascript)
Simple trunk-only history looks boring. That is the point. Boring history, exciting delivery. Chefโs kiss.
6. Trunk-based development is not the same as no branches
There are two common styles.
6.1 Direct-to-trunk
Developers commit directly to main.
gitGraph
commit id: "A"
commit id: "small fix"
commit id: "tiny feature"
commit id: "refactor"
Code language: JavaScript (javascript)
Best for:
- very small teams
- pair programming
- extremely strong CI
- mature engineering culture
- internal tools
- teams with high trust and fast rollback
6.2 Short-lived branch to trunk
Developers create tiny branches and merge them quickly through PR/MR.
gitGraph
commit id: "A"
branch small-change
checkout small-change
commit id: "B"
checkout main
merge small-change
commit id: "C"
Code language: JavaScript (javascript)
Best for most teams.
The trunk-based development reference describes short-lived feature branches as branches that are destined to come back as pull requests into main/trunk.
7. Direct-to-trunk vs short-lived PR branches
| Area | Direct-to-trunk | Short-lived PR branch |
|---|---|---|
| Speed | Very high | High |
| Review | Pair/mob/post-commit review | Pull request review |
| Risk | Higher without discipline | Lower |
| CI requirement | Critical | Critical |
| Best for | tiny mature teams | most professional teams |
| Branch lifetime | none | hours to 1โ2 days |
| Governance | lighter | stronger |
| Common in enterprise? | less common | more common |
Recommended default:
Use short-lived PR branches into trunk.
Code language: PHP (php)
This gives you trunk-based development benefits while keeping review and CI gates.
8. Trunk-based development vs feature branch workflow
| Area | Feature branch workflow | Trunk-based development |
|---|---|---|
| Branch lifetime | can be days/weeks | hours/days |
| Integration | delayed | frequent |
| Release readiness | depends on branch discipline | trunk stays releasable |
| Merge conflicts | higher if branches live long | lower |
| Review size | can become large | small PRs |
| Feature flags | useful | very important |
| CI | important | critical |
| Delivery speed | medium/high | high |
| Team maturity needed | medium | high |
9. Trunk-based development vs Gitflow
| Area | Gitflow | Trunk-based development |
|---|---|---|
| Main branches | main + develop | mostly main |
| Feature branches | common | very short-lived |
| Release branches | normal | optional/rare |
| Hotfix branches | explicit | usually revert/fix forward/hotfix from trunk |
| Best for | scheduled/versioned releases | continuous delivery |
| Complexity | high | lower branch complexity |
| Speed | medium | high |
| Governance | branch-driven | automation-driven |
| Feature flags | useful | nearly essential |
| Risk control | release branches | CI, flags, rollback, progressive rollout |
Gitflow can be excellent for mobile, desktop, firmware, SDKs, or products with formal release windows. Trunk-based development is usually stronger for SaaS, APIs, web systems, platform services, and teams practicing continuous delivery.
10. The core rule
Integrate at least daily.
Prefer multiple times per day.
A branch that lives too long becomes a private universe.
Private universes eventually collide.
xychart-beta
title "Branch age vs integration risk"
x-axis ["1 hour", "1 day", "3 days", "1 week", "2 weeks", "1 month"]
y-axis "Integration risk" 0 --> 100
bar [5, 10, 25, 45, 75, 95]
Code language: JavaScript (javascript)
The exact numbers are conceptual, but the pattern is real: the longer the branch lives, the more assumptions drift.
11. The trunk-based development promise
Trunk-based development promises:
- less merge pain
- faster feedback
- cleaner releases
- more reliable CI
- smaller pull requests
- easier rollback
- simpler branch structure
- better continuous delivery
- less branch archaeology
- less โworks on my branchโ drama
But it only works when the team also commits to:
- small changes
- strong CI
- automated tests
- feature flags
- protected trunk
- observability
- rollback discipline
- fast code review
DORA lists trunk-based development as a technical capability associated with software delivery and operational performance, within its broader catalog of DevOps capabilities.
12. The basic trunk-based workflow
flowchart TD
A[Start from latest main] --> B[Create tiny branch]
B --> C[Make small change]
C --> D[Run local checks]
D --> E[Push branch]
E --> F[Open PR/MR]
F --> G[CI runs]
F --> H[Review]
G --> I{CI green?}
H --> J{Approved?}
I -- No --> C
J -- No --> C
I -- Yes --> K[Merge to main]
J -- Yes --> K
K --> L[Delete branch]
L --> M[Deploy/release safely]
Code language: JavaScript (javascript)
Commands
git checkout main
git pull --ff-only origin main
git checkout -b small/change-login-error
# edit files
make test
git add .
git commit -m "fix(auth): show clear error for expired session"
git push -u origin small/change-login-error
Code language: PHP (php)
After PR merge:
git checkout main
git pull --ff-only origin main
git branch -d small/change-login-error
git fetch --prune
13. The advanced trunk-based workflow
flowchart TD
A[Small work item] --> B[Design if risky]
B --> C[Short-lived branch]
C --> D[Code behind feature flag if incomplete]
D --> E[Local checks]
E --> F[PR/MR]
F --> G[Fast CI]
G --> H[Security and quality gates]
H --> I[Merge to trunk]
I --> J[Build immutable artifact]
J --> K[Deploy to lower environment]
K --> L[Progressive production rollout]
L --> M[Observe metrics]
M --> N{Healthy?}
N -- Yes --> O[Continue rollout]
N -- No --> P[Rollback / disable flag / revert]
Code language: PHP (php)
This is the grown-up version. Less drama. More control.
14. Branch naming in trunk-based development
Because branches are short-lived, branch names should be simple and meaningful.
Recommended patterns:
small/<description>
feature/<ticket>-<description>
bugfix/<ticket>-<description>
chore/<ticket>-<description>
docs/<ticket>-<description>
security/<ticket>-<description>
Code language: HTML, XML (xml)
Examples:
feature/EVP-123-add-device-filter
bugfix/EVP-224-fix-token-refresh
chore/EVP-301-upgrade-logging-lib
security/EVP-777-mask-api-key
docs/EVP-410-update-runbook
Avoid:
rajesh-work
test
final
new
changes
big-feature
do-not-delete
Code language: JavaScript (javascript)
That last one is how branches become haunted houses.
15. Branch lifetime policy
| Branch type | Ideal lifetime | Maximum recommended |
|---|---|---|
| tiny fix | minutes to hours | same day |
| small feature | hours to 1 day | 2โ3 days |
| refactor slice | hours to 1 day | 2โ3 days |
| risky change behind flag | 1โ2 days | under 1 week |
| experiment | hours/days | 1 week |
| release branch, if used | short stabilization window | product-dependent |
| long-lived feature branch | avoid | avoid |
Hard rule:
A trunk-based feature branch should not become a second integration branch.
16. Pull request size policy
Trunk-based development is powered by small PRs.
| PR size | Review quality |
|---|---|
| 1โ100 lines | excellent |
| 100โ300 lines | good |
| 300โ600 lines | acceptable with context |
| 600โ1,000 lines | risky |
| 1,000+ lines | split unless generated |
| 5,000+ lines | archaeology, not review |
Recommended:
Small PRs, fast review, fast merge.
17. What โsmallโ really means
A small change is not just fewer lines.
A small change has:
- one purpose
- clear rollback
- clear test scope
- clear owner
- low hidden risk
- readable diff
- limited blast radius
Bad PR:
Add payment retries, refactor billing, update UI, rename database fields, upgrade framework
Good PR split:
PR 1: add retry config type
PR 2: add idempotency key support
PR 3: add retry logic behind flag
PR 4: add metrics
PR 5: enable internally
PR 6: enable gradually
flowchart LR
A[Big risky feature] --> B[Safe slice 1]
A --> C[Safe slice 2]
A --> D[Safe slice 3]
A --> E[Safe slice 4]
B --> F[Merge to trunk]
C --> F
D --> F
E --> F
Code language: CSS (css)
18. The role of CI in trunk-based development
CI is not optional in trunk-based development.
CI answers:
Can this tiny change safely join trunk?
Code language: JavaScript (javascript)
flowchart TD
A[PR to main] --> B[Checkout]
B --> C[Install dependencies]
C --> D[Format check]
D --> E[Lint]
E --> F[Unit tests]
F --> G[Build]
G --> H[Integration tests]
H --> I[Security checks]
I --> J{Green?}
J -- Yes --> K[Merge allowed]
J -- No --> L[Merge blocked]
GitHub protected branch rules can require status checks, reviews, linear history, and other constraints before changes land on important branches.
19. CI speed matters
If CI takes too long, trunk-based development slows down.
| CI duration | Effect |
|---|---|
| under 5 minutes | excellent |
| 5โ10 minutes | good |
| 10โ20 minutes | acceptable |
| 20โ45 minutes | painful |
| 45+ minutes | developers batch changes and avoid frequent integration |
Best practice:
Fast CI for merge.
Deep CI after merge or nightly.
Two-level CI model
flowchart TD
A[PR CI] --> B[Fast checks]
B --> C[Merge to main]
C --> D[Post-merge CI]
D --> E[Deeper integration tests]
D --> F[Performance tests]
D --> G[Security scans]
D --> H[Nightly/regression]
Code language: CSS (css)
20. Required CI gates
Minimum gates
| Gate | Purpose |
|---|---|
| format check | consistent code |
| lint | static mistakes |
| unit tests | logic correctness |
| build | package validity |
| type check | compile/type safety |
| secret scan | prevent leaked credentials |
| dependency scan | vulnerable library detection |
Stronger gates
| Gate | Purpose |
|---|---|
| integration tests | cross-component confidence |
| contract tests | API compatibility |
| container scan | image safety |
| IaC scan | cloud misconfig detection |
| license scan | compliance |
| policy-as-code | enforce standards |
| smoke test | deployment confidence |
21. Protected trunk policy
Trunk must be protected.
Recommended rules for main:
No direct push for most teams
Pull request required
Required CI checks
At least one approval
CODEOWNERS for critical paths
No force push
No branch deletion
Secret scanning enabled
Linear history optional
Admin bypass audited
GitHub documentation says branch protection rules can define whether collaborators can delete or force-push to a branch and can require conditions such as status checks or linear history.
22. Merge strategy for trunk-based development
Common merge options:
| Merge type | Description | Fit for TBD |
|---|---|---|
| squash merge | PR becomes one clean commit | excellent default |
| rebase merge | keeps linear history | good for disciplined teams |
| merge commit | preserves branch shape | okay, but noisier |
| fast-forward | pointer moves only | good for direct/trunk-heavy teams |
Recommended default:
Use squash merge for normal small PRs.
Use rebase merge if commits are clean.
Avoid noisy merge commits for tiny branches unless audit requires them.
Code language: PHP (php)
23. Commit message standard
Use meaningful commit messages.
Recommended:
<type>(scope): summary
Code language: HTML, XML (xml)
Examples:
feat(auth): add session renewal flag
fix(payment): handle gateway timeout
chore(ci): speed up unit test cache
docs(runbook): add rollback steps
test(api): add contract test for vehicle endpoint
Code language: HTTP (http)
Conventional Commits defines a lightweight structure for commit messages that gives human-readable and machine-readable meaning to history, and aligns with semantic versioning concepts such as features, fixes, and breaking changes.
24. Feature flags: the engine of trunk-based development
Feature flags let teams merge incomplete or risky work into trunk safely.
Without feature flags:
Feature incomplete โ keep branch open
With feature flags:
Feature incomplete โ merge to trunk with flag OFF
Code language: JavaScript (javascript)
Martin Fowlerโs feature toggle article explains that release toggles allow in-progress features to be checked into a shared integration branch while keeping that branch deployable to production.
flowchart TD
A[Code feature] --> B[Wrap with feature flag]
B --> C[Merge to trunk]
C --> D[Deploy with flag OFF]
D --> E[Enable for internal users]
E --> F[Enable for beta users]
F --> G[Enable for 10%]
G --> H[Enable for 100%]
H --> I[Remove flag]
Code language: CSS (css)
25. Feature flag types
| Flag type | Purpose | Example |
|---|---|---|
| release flag | hide incomplete feature | new_checkout_enabled |
| ops flag | kill switch | payment_retry_enabled |
| experiment flag | A/B test | homepage_variant_b |
| permission flag | customer/role control | premium_reports_enabled |
| migration flag | gradual backend switch | use_new_search_index |
Martin Fowlerโs feature-flag taxonomy discusses release toggles, experiment toggles, ops toggles, and permissioning toggles as different uses of feature flags.
26. Feature flag rules
Every flag must have:
| Metadata | Example |
|---|---|
| owner | payments team |
| creation date | 2026-07-07 |
| expiry date | 2026-08-07 |
| default state | off |
| rollout plan | internal โ 10% โ 50% โ 100% |
| rollback action | disable flag |
| cleanup ticket | remove after rollout |
Flag hygiene rule
A feature flag without an expiry date is future technical debt.
Atlassian notes that feature flags complement trunk-based development and encourage small-batch updates by allowing inactive code paths to be activated later.
27. Branch by abstraction
Branch by abstraction is how teams do large changes without long-lived branches.
Instead of building a giant feature branch for months, you introduce an abstraction and migrate gradually.
flowchart TD
A[Old implementation] --> B[Create abstraction/interface]
B --> C[Route old behavior through abstraction]
C --> D[Add new implementation behind flag]
D --> E[Migrate callers gradually]
E --> F[Remove old implementation]
Code language: CSS (css)
Example:
OldPaymentClient
โ
PaymentProvider interface
โ
StripeProvider + NewProvider
โ
flag: use_new_payment_provider
PR sequence
PR 1: add PaymentProvider interface
PR 2: route old provider through interface
PR 3: add new provider behind flag
PR 4: migrate one payment path
PR 5: migrate all paths
PR 6: remove old provider and flag
Code language: JavaScript (javascript)
This is one of the most powerful advanced techniques in trunk-based development.
28. Expand-migrate-contract for databases
Database changes are dangerous in trunk-based development unless phased.
Use:
Expand โ Migrate โ Contract
flowchart LR
A[Expand schema] --> B[Deploy backward-compatible app]
B --> C[Backfill data]
C --> D[Switch reads/writes]
D --> E[Contract old schema]
Code language: CSS (css)
Bad migration
ALTER TABLE users DROP COLUMN name;
Safer migration
1. Add new column.
2. Deploy app that writes both old and new.
3. Backfill data.
4. Switch reads to new column.
5. Wait and monitor.
6. Remove old column later.
Code language: PHP (php)
Rule
Trunk must support safe rolling deployment.
That means new code and old code may run together during rollout.
29. Release from trunk
In trunk-based development, releases usually come from trunk.
flowchart TD
A[main/trunk] --> B[Build artifact]
B --> C[Deploy to staging]
C --> D[Deploy to production]
D --> E[Release using flag or rollout]
Code language: CSS (css)
Common release models:
| Model | How it works |
|---|---|
| deploy every merge | every green main commit deploys |
| scheduled deploy from trunk | deploy selected trunk build |
| release tag from trunk | tag known-good commit |
| release branch from trunk | short stabilization branch |
| feature flag release | deploy code, release later |
| progressive delivery | canary/blue-green/rolling |
30. Release branches in trunk-based development
Trunk-based development tries to avoid long-lived development branches, but short-lived release branches can still exist.
Use release branches when:
- mobile app store approval is needed
- enterprise release certification is needed
- a release needs short stabilization
- production patching must happen separately
- customers need supported old versions
Do not use release branches as hidden feature branches.
gitGraph
commit id: "A"
commit id: "B"
branch release/2.4
checkout release/2.4
commit id: "release fix"
checkout main
commit id: "future work"
checkout release/2.4
commit id: "tag v2.4.0"
Code language: JavaScript (javascript)
Microsoft describes using trunk-based branching together with a release branch flow model to develop products quickly, deploy regularly, and deliver changes safely to production.
31. Release branch rules
If you use release branches with trunk-based development:
Allowed:
bug fixes
version bump
release notes
stabilization fixes
safe configuration corrections
Not allowed:
new features
big refactors
experimental dependency upgrades
unrelated cleanup
architecture rewrites
Code language: JavaScript (javascript)
Rule:
Release branches stabilize; trunk continues.
32. Hotfixes in trunk-based development
Hotfix strategies:
| Situation | Best action |
|---|---|
| bad feature behind flag | disable flag |
| bad commit on trunk | revert commit |
| urgent production bug | fix on trunk, deploy |
| release branch active | fix trunk and cherry-pick/backport |
| old version affected | patch support/release branch |
flowchart TD
A[Production issue] --> B{Feature flag?}
B -- Yes --> C[Disable flag]
B -- No --> D{Bad commit?}
D -- Yes --> E[Revert on trunk]
D -- No --> F[Small hotfix to trunk]
F --> G[CI]
G --> H[Deploy]
E --> H
C --> I[Monitor]
H --> I
33. Rollback strategy
In trunk-based development, rollback must be boring.
Rollback methods:
| Method | Best for |
|---|---|
| disable feature flag | bad feature behavior |
| revert commit | bad source change |
| redeploy previous artifact | bad deployment |
| rollback config | bad configuration |
| pause rollout | canary/rolling issue |
| fix forward | tiny safe correction |
| restore backup | data loss/corruption |
flowchart TD
A[Issue detected] --> B{Can flag disable?}
B -- Yes --> C[Turn flag off]
B -- No --> D{Previous artifact known?}
D -- Yes --> E[Redeploy previous artifact]
D -- No --> F{Bad commit known?}
F -- Yes --> G[Revert commit]
F -- No --> H[Fix forward]
34. Progressive delivery
Progressive delivery is a natural partner for trunk-based development.
Strategies:
- rolling deployment
- canary deployment
- blue-green deployment
- feature flag rollout
- shadow traffic
- A/B testing
Kubernetes rolling updates gradually replace old Pods with new Pods and can keep an application available by routing traffic only to Pods that can serve requests.
flowchart LR
A[Deploy v2 to 1%] --> B[Check metrics]
B --> C[Deploy to 10%]
C --> D[Check metrics]
D --> E[Deploy to 50%]
E --> F[Check metrics]
F --> G[Deploy to 100%]
Code language: CSS (css)
Canary gates
| Metric | Watch for |
|---|---|
| error rate | increase |
| latency | regression |
| CPU/memory | saturation |
| logs | new exceptions |
| traces | slow spans |
| business metric | conversion/login/payment drop |
| user reports | complaints |
35. Trunk-based development and continuous delivery
Trunk-based development is one of the strongest foundations for continuous delivery.
Why?
Continuous delivery needs releasable code.
Releasable code needs frequent integration.
Frequent integration needs trunk-based development discipline.
flowchart LR
A[Small changes] --> B[Frequent integration]
B --> C[Fast CI]
C --> D[Always releasable trunk]
D --> E[Continuous delivery]
E --> F[Fast feedback]
Code language: CSS (css)
AWSโs Git branching guidance describes trunk-based development as keeping the codebase continuously releasable by integrating changes frequently and relying on automated testing and continuous integration.
36. Trunk-based development for small teams
Small team model:
main
or:
main
short-lived/*
Rules:
- pair review or PR review
- CI required
- small commits
- feature flags for incomplete work
- deploy frequently
- revert quickly
flowchart TD
A[Developer] --> B[Small change]
B --> C[CI]
C --> D[main]
D --> E[Deploy]
Code language: CSS (css)
Small teams can move very fast with trunk-based development because communication cost is low.
37. Trunk-based development for larger teams
Large teams need more control.
Recommended:
main
short-lived feature branches
CODEOWNERS
path-based CI
feature flags
release tags
progressive delivery
flowchart TD
A[Team A change] --> D[main]
B[Team B change] --> D
C[Team C change] --> D
D --> E[CI fan-out]
E --> F[Build affected artifacts]
F --> G[Deploy safely]
Code language: CSS (css)
Controls:
- CODEOWNERS
- branch protection
- required checks
- selective CI
- service ownership
- feature flag ownership
- release dashboards
- on-call ownership
38. Trunk-based development in monorepos
Trunk-based development works very well in monorepos, but only with tooling.
Monorepo structure:
repo/
apps/
web/
admin/
services/
auth/
payment/
notification/
packages/
common/
ui/
infra/
docs/
Needs:
- path-based CI
- affected-project detection
- CODEOWNERS
- dependency graph
- caching
- small PRs
- feature flags
- fast revert
flowchart TD
A[Commit to main] --> B[Detect changed paths]
B --> C[Find affected services/packages]
C --> D[Run targeted tests]
D --> E[Build affected artifacts]
E --> F[Deploy only affected services]
Code language: CSS (css)
39. Trunk-based development for microservices
Microservices need independent deployability.
Do not use branches to coordinate service compatibility.
Use:
- backward-compatible APIs
- contract tests
- feature flags
- versioned endpoints
- tolerant readers
- gradual rollout
- observability
flowchart TD
A[Service A change] --> B[Backward-compatible API]
B --> C[Contract tests]
C --> D[Merge to trunk]
D --> E[Deploy Service A]
E --> F[Monitor Service B/C consumers]
Code language: CSS (css)
Bad:
service-a waits for service-b branch
service-b waits for service-c branch
everything waits for release day
That is distributed merge hell with extra steps.
40. Trunk-based development for Infrastructure as Code
IaC repositories can use trunk-based development, but with strong plan review.
Recommended:
main
short-lived/*
Workflow:
flowchart TD
A[Small infra change] --> B[PR to main]
B --> C[terraform fmt]
C --> D[terraform validate]
D --> E[terraform plan]
E --> F[security scan]
F --> G[cost/blast-radius review]
G --> H[merge to main]
H --> I[apply through pipeline]
Code language: CSS (css)
Rules:
- no direct prod apply from laptop
- plan output required
- cost/security review for risky changes
- production approval where needed
- state protected
- secrets never committed
- small changes only
41. Trunk-based development for Kubernetes GitOps
GitOps plus trunk-based development is a strong combination.
Recommended:
main
short-lived/*
Repository layout:
gitops/
apps/
auth/
payment/
clusters/
dev/
staging/
production/
platform/
ingress/
monitoring/
Flow:
flowchart LR
A[App source merged to main] --> B[Build image]
B --> C[Update GitOps repo]
C --> D[PR to main]
D --> E[Argo CD / Flux sync]
E --> F[Kubernetes cluster]
Code language: CSS (css)
Rules:
- Git is desired state.
- Changes go through PR.
- Production changes are reviewed.
- Rollback is Git revert or previous artifact.
- Use immutable image tags/digests.
- Build once, promote same artifact.
42. Trunk-based development for mobile apps
Mobile apps often need release branches even if development is trunk-based.
Recommended:
main
short-lived/*
release/ios-5.1.0
release/android-5.1.0
Flow:
flowchart TD
A[main] --> B[release/mobile-5.1.0]
B --> C[QA]
C --> D[TestFlight/Internal track]
D --> E[App Store/Play review]
E --> F[Staged rollout]
F --> G[tag v5.1.0]
Code language: CSS (css)
Rules:
- trunk continues normal development
- release branch gets stabilization fixes only
- tags match shipped builds
- backend APIs remain backward compatible
- use remote config/feature flags carefully
43. Trunk-based development for libraries and SDKs
Libraries can use trunk-based development with release tags and support branches.
Recommended:
main
short-lived/*
release/* optional
support/* optional
Rules:
- main contains latest development
- tag every release
- use Semantic Versioning
- backport critical fixes if supporting old versions
- use release branches only when stabilization is needed
44. Trunk-based development and semantic versioning
Trunk-based development does not remove versioning.
Use tags:
v1.0.0
v1.1.0
v1.1.1
v2.0.0
Code language: CSS (css)
Common mapping:
| Change | Version impact |
|---|---|
| bug fix | patch |
| backward-compatible feature | minor |
| breaking change | major |
| internal refactor | no public version change |
| security fix | patch or major depending compatibility |
45. Trunk-based development PR template
## Summary
Explain the change in 2โ5 lines.
## Why
What problem does this solve?
## Scope
- [ ] Small isolated change
- [ ] Behind feature flag
- [ ] Refactor only
- [ ] Bug fix
- [ ] Infrastructure/config change
## Testing
- [ ] Unit tests
- [ ] Integration tests
- [ ] Contract tests
- [ ] Manual validation
- [ ] Not applicable
## Risk
Low / Medium / High
## Feature flag
Flag name:
Default state:
Rollout plan:
Cleanup ticket:
## Rollback
How can this be reverted, disabled, or rolled back?
## Checklist
- [ ] CI passes
- [ ] Change is small
- [ ] No secrets committed
- [ ] Backward compatibility considered
- [ ] Observability considered
- [ ] Rollback path known
Code language: PHP (php)
46. Company-ready trunk-based policy
Trunk-Based Development Policy
1. main is the single shared trunk.
2. main must always remain healthy and releasable.
3. Long-lived feature branches are not allowed.
4. Developers must use small changes and short-lived branches.
5. Branches should merge within hours or a few days.
6. All changes must pass CI before merge.
7. Pull requests must be small and reviewable.
8. Incomplete features must be hidden behind feature flags.
9. Feature flags must have owners and expiry dates.
10. Production releases must be traceable to commits and artifacts.
11. Rollback must be possible through flag disablement, revert, or redeploy.
12. CI/CD pipeline changes require owner review.
13. Database changes must be backward compatible.
14. Stale branches must be deleted.
15. Trunk health is a team responsibility.
Code language: JavaScript (javascript)
47. Branch protection policy
For main:
- require pull request
- require status checks
- require one or more approvals
- require CODEOWNERS for critical paths
- block force push
- block deletion
- require branch to be up to date before merge
- require secret scanning
- optionally require signed commits
Code language: JavaScript (javascript)
For short-lived/* branches:
- owner can push
- CI runs automatically
- PR required before merge
- delete after merge
Code language: JavaScript (javascript)
48. CODEOWNERS example
# Platform and CI/CD
/.github/workflows/ @devops-team
/infra/ @platform-team
# Services
/services/auth/ @identity-team
/services/payment/ @payment-team
/services/notification/ @backend-team
# Sensitive areas
/security/ @security-team
/database/migrations/ @backend-leads @platform-team
# Shared libraries
/packages/common/ @architecture-team
Code language: PHP (php)
49. Developer daily checklist
Before opening PR:
- Branch is based on latest main.
- Change is small.
- Tests are added or updated.
- Local checks pass.
- Feature flag exists if feature is incomplete.
- Rollback path is clear.
- No secrets are committed.
- PR description explains why.
Before merging:
- CI is green.
- Review is complete.
- Risk is understood.
- Main is healthy.
- Feature flag default is safe.
- Monitoring exists if production behavior changes.
Code language: JavaScript (javascript)
50. Reviewer checklist
Reviewers should check:
- Is this change small enough?
- Does it belong on trunk now?
- Is incomplete work hidden?
- Are tests adequate?
- Is it backward compatible?
- Is rollback possible?
- Is the feature flag safe?
- Is observability adequate?
- Does it affect database schema?
- Does it affect deployment or security?
51. Release checklist
Before production rollout:
- Artifact built from main.
- Commit SHA known.
- CI passed.
- Security scans passed.
- Feature flags configured.
- Database migrations safe.
- Rollback plan ready.
- Dashboard ready.
- Alerts active.
- On-call owner aware.
Code language: JavaScript (javascript)
After rollout:
- Monitor errors.
- Monitor latency.
- Monitor business metric.
- Continue/pause rollout.
- Remove old feature flags after success.
- Document incident if rollback was needed.
Code language: PHP (php)
52. Migration path from Gitflow to trunk-based development
Many teams cannot jump directly from Gitflow to trunk-based development.
Use a gradual migration.
flowchart TD
A[Current Gitflow] --> B[Protect develop/main]
B --> C[Reduce feature branch lifetime]
C --> D[Improve CI speed]
D --> E[Introduce feature flags]
E --> F[Merge features to develop daily]
F --> G[Remove long-lived develop dependency]
G --> H[Make main the trunk]
H --> I[Release from main]
Code language: CSS (css)
Step-by-step
| Step | Action |
|---|---|
| 1 | measure current branch age |
| 2 | limit feature branches to under one week |
| 3 | require CI on PRs |
| 4 | add feature flags |
| 5 | split large PRs |
| 6 | make develop always green |
| 7 | merge more frequently |
| 8 | move toward main as trunk |
| 9 | use release branches only when needed |
| 10 | delete stale branches |
53. Readiness checklist
You are ready for trunk-based development when:
- CI is reliable.
- CI is fast enough.
- Tests catch important failures.
- Developers can make small PRs.
- Feature flags are available.
- Main branch is protected.
- Rollback is known.
- Production has observability.
- Team can review quickly.
- Database changes are backward compatible.
Code language: PHP (php)
You are not ready when:
- CI is flaky.
- Tests are weak.
- PRs are huge.
- Developers keep branches for weeks.
- No feature flag system exists.
- Main breaks often.
- Rollback is manual panic.
- Production monitoring is weak.
54. Trunk-based anti-patterns
Anti-pattern 1: Everyone pushes broken code to main
That is not trunk-based development.
Fix:
protect main
require CI
require review or pair programming
Code language: JavaScript (javascript)
Anti-pattern 2: Short-lived branches become long-lived branches
Problem:
feature/big-refactor lives for 6 weeks
Fix:
split work
use feature flags
use branch by abstraction
merge small slices
Code language: PHP (php)
Anti-pattern 3: Feature flags never get removed
Problem:
hundreds of flags
nobody knows which are active
Fix:
owner
expiry date
cleanup ticket
flag dashboard
regular cleanup
Anti-pattern 4: CI is too slow
Problem:
developers batch changes because feedback takes too long
Fix:
parallelize tests
cache dependencies
split fast and deep CI
run targeted tests
remove flaky tests from merge gate only with owner/deadline
Code language: JavaScript (javascript)
Anti-pattern 5: Big bang release from trunk
Problem:
many hidden features enabled at once
Fix:
progressive rollout
canary
feature flags
small releases
Anti-pattern 6: Database changes break rolling deploys
Problem:
new code requires new schema immediately
old pods still running
deployment fails
Code language: JavaScript (javascript)
Fix:
expand-migrate-contract
backward-compatible migrations
safe rollout
55. Trunk-based development metrics
Measure the system.
| Metric | Why it matters |
|---|---|
| branch age | integration delay |
| PR size | review quality |
| PR cycle time | flow speed |
| CI duration | feedback speed |
| CI failure rate | quality signal |
| flaky test rate | pipeline trust |
| main branch health | trunk stability |
| deployment frequency | delivery flow |
| change failure rate | production risk |
| rollback time | recovery strength |
| feature flag age | flag debt |
Healthy signals:
branches live hours/days
PRs are small
main is usually green
CI is trusted
rollbacks are fast
feature flags are removed
deployments are routine
56. Practical examples
Example 1: small bug fix
git checkout main
git pull --ff-only origin main
git checkout -b bugfix/clear-login-error
# edit
make test
git add .
git commit -m "fix(auth): show clear login error"
git push -u origin bugfix/clear-login-error
Code language: PHP (php)
Merge same day.
Example 2: incomplete feature with flag
git checkout main
git pull --ff-only origin main
git checkout -b feature/payment-retry-flag
Code:
if payment_retry_enabled:
retry_gateway_timeout()
else:
current_payment_flow()
Code language: PHP (php)
Commit:
git commit -m "feat(payment): add retry flow behind feature flag"
Code language: JavaScript (javascript)
Deploy with flag off. Enable gradually later.
Example 3: large refactor using branch by abstraction
PR 1: introduce interface
PR 2: route old implementation through interface
PR 3: add new implementation behind flag
PR 4: migrate one caller
PR 5: migrate remaining callers
PR 6: remove old implementation
Code language: JavaScript (javascript)
No giant branch. No merge war. No โsee you in six weeksโ energy.
57. Trunk-based development for teams: operating model
Developer
- makes small changes
- keeps branch fresh
- writes tests
- uses feature flags
- opens small PRs
- merges quickly
Reviewer
- reviews quickly
- focuses on correctness/risk
- encourages smaller PRs
- checks rollback
- blocks unsafe trunk changes
Tech lead
- watches trunk health
- splits large work
- enforces flag cleanup
- improves CI reliability
- guides migration patterns
DevOps/platform
- keeps CI fast
- enforces branch protection
- provides deployment safety
- enables observability
- automates rollback
Product
- accepts incremental delivery
- uses feature flags for release timing
- avoids forcing giant branches
- helps define rollout phases
58. Trunk-based development decision tree
flowchart TD
A[Should we use trunk-based development?] --> B{Can main be protected and kept green?}
B -- No --> C[Improve CI and branch protection first]
B -- Yes --> D{Can changes be small?}
D -- No --> E[Introduce slicing and branch by abstraction]
D -- Yes --> F{Do we have feature flags?}
F -- No --> G[Use short branches carefully and add flags]
F -- Yes --> H{Can we rollback quickly?}
H -- No --> I[Improve rollback and observability]
H -- Yes --> J[Use trunk-based development]
Code language: PHP (php)
59. One-page trunk-based standard
Trunk-Based Development Standard
Branch model:
- main is the trunk.
- short-lived branches are allowed.
- long-lived feature branches are not allowed.
- release branches are optional and short-lived.
Rules:
- main must always be healthy.
- all changes are small.
- all changes pass CI.
- incomplete features use feature flags.
- branches merge within hours or days.
- production releases are traceable.
- rollback is planned.
- feature flags are removed after rollout.
- stale branches are deleted.
Merge policy:
- squash merge by default.
- rebase local branches only.
- no force push to main.
- revert instead of rewriting shared history.
Release policy:
- build from main.
- promote immutable artifacts.
- use flags/canary/rolling rollout.
- tag releases when needed.
- monitor after deployment.
Code language: JavaScript (javascript)
60. Final wisdom
A beginner thinks trunk-based development means:
Everyone commits to main.
A senior engineer knows it means:
Everyone integrates safely and frequently.
An architect knows it means:
A delivery system built around small changes, fast feedback, automation, feature flags, rollback, and continuous learning.
Trunk-based development is not a shortcut.
It is discipline.
It removes branch complexity and replaces it with engineering maturity:
small batches
fast CI
strong tests
feature flags
protected main
safe rollout
quick rollback
observability
Code language: PHP (php)
Final principle:
Trunk-based development is not about having fewer branches.
It is about having fewer delayed problems.
When done badly, it breaks main.
When done well, it becomes one of the strongest foundations for continuous delivery.
Iโm a DevOps/SRE/DevSecOps/Cloud Expert passionate about sharing knowledge and experiences. I have worked at Cotocus. I share tech blog at DevOps School, travel stories at Holiday Landmark, stock market tips at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow , and SEO strategies at Wizbrand.
Do you want to learn Quantum Computing?
Please find my social handles as below;
Rajesh Kumar Personal Website
Rajesh Kumar at YOUTUBE
Rajesh Kumar at INSTAGRAM
Rajesh Kumar at X
Rajesh Kumar at FACEBOOK
Rajesh Kumar at LINKEDIN
Rajesh Kumar at WIZBRAND
Find Trusted Cardiac Hospitals
Compare heart hospitals by city and services โ all in one place.
Explore Hospitals