Feature Flags vs Feature Branches: When to Use Each
The False Dichotomy
Developers often frame feature flags vs feature branches as an either/or choice. In reality, they solve different problems and work best together. Feature branches manage code integration. Feature flags manage feature release. Understanding this distinction is key to a healthy deployment workflow.
What Are Feature Branches?
Feature branches are a Git workflow where each new feature is developed on a separate branch. When the feature is ready, the branch is merged into the main branch (usually main or develop).
git checkout -b feature/new-payment-flow
# ... work on the feature ...
git push origin feature/new-payment-flow
# Create a pull request, get reviews, merge
Advantages of Feature Branches
- Isolation: Changes are isolated until the branch is merged
- Code review: Pull requests enable structured review
- CI checks: Automated tests run on each branch before merging
- Familiar: Every developer knows Git branching
Problems with Feature Branches
- Long-lived branches diverge: The longer a branch lives, the harder the merge. Conflicts accumulate, and integration becomes painful.
- Delayed feedback: You don't know if your feature works in production until it's merged and deployed.
- All-or-nothing releases: Merging a feature branch means releasing it. There's no way to deploy the code but hide the feature.
- Merge conflicts: Large branches touching many files create merge hell, especially on active codebases.
What Are Feature Flags?
Feature flags wrap new functionality in a conditional check. The code is deployed to production but only activated when the flag is enabled. This decouples deployment from release.
const showNewPayment = rollgate.isEnabled('new-payment-flow', { userId: user.id });
if (showNewPayment) {
return <NewPaymentFlow />;
}
return <CurrentPaymentFlow />;
Advantages of Feature Flags
- Deploy anytime: Code goes to production even if the feature isn't ready for users
- Gradual rollout: Enable for 1% of users, then 10%, then 100%
- Instant rollback: Disable a flag in seconds, no redeployment needed
- Targeting: Show features to specific users, teams, or segments
- Trunk-based development: Everyone commits to
main, reducing merge conflicts
Problems with Feature Flags
- Code complexity: Two code paths mean more logic to maintain
- Stale flags: Unused flags accumulate as technical debt
- Testing surface: You need to test both flag states
- Requires discipline: Flags need to be cleaned up after full rollout
When to Use Feature Branches
Feature branches are the right choice when:
- Short-lived work (1-3 days): Bug fixes, small features, refactors that can be reviewed and merged quickly
- Code review is essential: You want a structured PR workflow with approvals
- No production risk: The change doesn't need gradual rollout or targeting
- Open-source contributions: External contributors need isolated branches for PRs
When to Use Feature Flags
Feature flags are the right choice when:
- Gradual rollout needed: You want to release to a percentage of users first
- Long-running features: Work that spans multiple sprints or weeks
- Production testing: You need to verify behavior in production before full release
- Kill switch required: The feature could impact system stability
- User targeting: Different users should see different experiences
- A/B testing: You're running experiments between variants
The Best Approach: Use Both
The most effective teams use short-lived feature branches combined with feature flags:
- Create a short-lived branch for a small piece of work (1-2 days)
- Wrap new UI or behavior behind a feature flag
- Merge to main quickly — the flag is off, so nothing changes for users
- Deploy to production — the code is there but hidden
- Enable the flag gradually when the full feature is ready
- Clean up the flag once the feature is at 100%
This gives you the best of both worlds:
- Short branches avoid merge conflicts and integration pain
- Feature flags give you release control without deployment pressure
- Trunk-based development keeps the main branch always deployable
- Continuous delivery becomes natural, not scary
Trunk-Based Development with Feature Flags
Trunk-based development (TBD) is the practice of keeping branches short (hours to days) and merging to main frequently. Feature flags are what make TBD safe for large features:
Day 1: Merge backend API behind flag → Deploy → Flag off
Day 2: Merge UI component behind flag → Deploy → Flag off
Day 3: Merge integration tests → Deploy → Flag off
Day 4: Enable flag for internal team → Test in production
Day 5: Rollout to 10% → Monitor metrics
Day 7: Rollout to 100% → Remove flag
Each merge is small, easy to review, and safe to deploy. The feature grows incrementally in production without affecting users until you decide it's ready.
Real-World Comparison
| Aspect | Feature Branches Only | Feature Branches + Flags |
|---|---|---|
| Branch lifetime | Days to weeks | Hours to days |
| Merge conflicts | Frequent | Rare |
| Release control | None (merge = release) | Full (gradual, targeted) |
| Rollback speed | Minutes (redeploy) | Seconds (toggle flag) |
| Production testing | Not possible | Easy |
| A/B testing | Not possible | Built-in |
Conclusion
Feature branches and feature flags aren't competing approaches — they're complementary tools. Use feature branches for code management and review. Use feature flags for release management and safety. Together, they enable fast, safe, continuous delivery.
If you're still doing long-lived feature branches with big-bang releases, consider adding feature flags to your workflow. Start with one flag on your next feature and experience the difference.
Get started with Rollgate — free tier, no credit card required.