Blog #46: Feature Flag – The 'Lifebuoy' for Risky Releases
Analyzing the decision to implement a Feature Flag system for a financial project with a team of 12 and the pressure of no room for error.
I once led a group of 12 developers building a new Core Banking system. The deadline was 3 weeks away, and we had to replace the entire "Quick Transfer" flow—an extremely sensitive feature. The project's scale was hundreds of thousands of transactions per day. The pressure then wasn't just to complete, but to ensure that if any error occurred on Production, we had a way to roll back immediately without spending 30 minutes to build and deploy again from scratch.
The Problem: "Holding Breath" When Hitting the Deploy Button
The biggest problem was the difference between the Staging and Production environments. Despite thorough testing, we couldn't anticipate how the system would behave under actual load with millions of database records.
We needed a mechanism to:
- Deploy new code without making it immediately visible to all users.
- Be able to "turn off" the new feature and go back to the old one in just 1 second if a bug was detected.
Options Considered
We stood between 2 choices:
Option 1: Git Branching Strategy (Traditional)
- Solution: Keep the old feature on the
masterbranch, new feature on thefeature/new-transferbranch. If a bug occurs, revert the code and re-deploy. - Pros: No additional development cost for a management system.
- Cons: Long rollback time (at least 15-20 minutes for CI/CD to run). Extremely high risk of merge conflicts when many people work together.
Option 2: Feature Flag Implementation (Modern Architecture)
- Solution: Deploy both old and new code simultaneously. Use a configuration variable from the server to decide which code will be executed.
- Pros: Instant rollback (just change the variable value on a Dashboard). Allows for Canary Release (only opening to 1-5% of users for testing).
- Cons: Code will become more cluttered as it must be wrapped by
if/elsestatements. Needs an additional Flag manager (like LaunchDarkly or self-built).
Final Decision and Analysis
I decided to choose Option 2. The safety of the financial system was more important than the beauty of the code at that time.
// Pseudo-code of Feature Flag implementation
const MoneyTransfer = () => {
const { isEnabled } = useFeatureFlag('new_transfer_flow');
if (isEnabled) {
return <NewTransferFlow />;
}
return <OldTransferFlow />;
};
Impact on Performance: There is a small latency (a few ms) to fetch the Flag value from the server. We optimized by caching the Flag in LocalStorage or embedding it directly into the initial sitemap payload.
Impact on Maintainability: This is a burden. The code contains more "garbage" statements. I had to set a rule: Immediately after the new feature stabilizes (after 1 week), the team must have a "Cleanup" task to remove the old code and the if/else statements related to that Flag.
Impact on Team: Juniors initially found it troublesome to write code in 2 places. But after witnessing a Logic bug fixed with just one click to turn off the Flag in 5 seconds, they understood the value of this "defensive" approach.
Self-Reflection: Was it Over-engineering?
Many would say: "Just write clean code, test it well, why bother with Feature Flags?". But in reality, in an Enterprise environment, nothing is 100% certain.
If I were starting over, I would still choose Feature Flags. In fact, I would apply them earlier for every major feature. It's not just a technical tool; it's a "tranquilizer" for both leadership and technical teams during risky releases.
Notes on the day we learned how to control our own risks.
Series • Part 46 of 50