Branching & feature flags

Trunk-based dev; decouple deploy from release.

Intermediate30 min · lesson 5 of 15

How a team branches, merges, and releases code shapes how fast and safely it can deliver. Trunk-based development and feature flags are the modern patterns that enable continuous integration and decouple deployment from release.

Trunk-based development

Trunk-based development favors short-lived branches merged frequently into main, rather than long-lived feature branches that diverge for weeks and cause painful, risky merges. Developers integrate small changes continuously, so the mainline is always current and merge conflicts stay small — this is what makes continuous integration actually continuous. Incomplete work is merged safely behind feature flags (toggles) that keep new features turned off in production until they are ready. The result is that everyone works close to the mainline, integration is constant and cheap, and the codebase is always in a releasable state, which is the prerequisite for frequent, low-risk deployment.

trunk-based flow with flags
# Short-lived branch, merged in days not weeks:
main ──●──●──●──●──●──●── (always releasable)
\__/ \__/ \__/
feature branches: small, frequent, behind flags
# Merge incomplete work turned OFF, enable later:
if (featureFlags.isEnabled('new-checkout')) { // off in prod until ready
renderNewCheckout();
}
# Deploy the code dark; release the feature on a business decision.

Decoupling deploy from release

Feature flags enable a powerful separation: deployment (shipping code to production) becomes distinct from release (turning a feature on for users). You can deploy code frequently and safely — it is dark until a flag enables it — then release features on a business schedule, gradually to a subset of users, or roll them back instantly by flipping the flag without a redeploy. This reduces deployment risk dramatically and supports progressive delivery (canary via flags). Combined with trunk-based development and a protected, always-green mainline, this is the flow that lets teams deploy many times a day with confidence. The DevOps engineer establishes these patterns so the team can integrate constantly and release deliberately, which is the heart of high-performing delivery.

Deploy dark, release on demand
1short-lived branch
merged frequently to main
2merge behind a flag
incomplete work stays off
3deploy code (dark)
shipped but not visible
4release via flag
enable gradually, roll back instantly
Trunk-based development plus feature flags decouple deploy from release — ship constantly, turn features on deliberately.
Long-lived feature branches break continuous integration
A branch that lives for weeks diverges far from main, so its eventual merge is large, conflict-ridden, and risky — the opposite of continuous integration. Keep branches short-lived and merge frequently behind feature flags, so integration stays small and cheap and the mainline is always releasable.