🎓 Increasing Development Speed & Stability With Feature Flags
Make engineering look good by adding more control to your deliverables.
A senior engineer is responsible for contributing code that is high quality and stable when deployed and released.
Often times, development of a feature comes in multiple phases, across many contributors, touching many areas of your code base. Every one of these touch points increases the risk of new bugs or regressions.
So how do you deliver quickly while minimizing risk?
Feature flags! 🏳️
What are feature flags?
A feature flag is a software implementation that allows you to control the flow of your code (“feature”), by switching it on or off (“flag”).
Feature flags are added to the code and deployed once, then toggled without additional code changes or deployments. This allows your team to skip the deployment pipeline and quickly disable troublesome areas to reduce exposure and user disappointment.
More advanced feature flag implementations include the ability to segment users, allowing flags to be toggled for specific users or groups. For example: users who opt into beta features, customers at specific subscription tiers, geographical targeting, etc.
Feature flags are also referred to as feature toggles or feature switches. Different terms, same concept.
What feature flags are not.
Flags are not permanent.
It’s important to distinguish that feature flags are temporary, and are meant to be removed when you no longer need to toggle flows based on development and release cycles.
When your feature is 100% available to its target audience, you should remove the flag from your code.
Leaving flags in your code that are no longer needed contribute to bloat, confusion among your team, and even resentment and morale issues. Read more about Broken Windows in this previous issue:
Flags are not access control.
If your platform includes features that are only accessible at certain tiers, you should use proper authorization checks to protect the flow of that code.
You can use feature flags during development of said feature. The feature flag determines who is sent to the access control check.
Feature flags are not a direct replacement of access control. Flags should be the first gate that your code passes through. Here’s a pseudo-code example using the early return pattern:
if (featureIsEnabled('analytics') === false) {
// Feature flag is disabled; no access, stop here.
return;
}
if (user.can('analytics.view') === false) {
// Feature is enabled, but current user does not have access.
return;
}
// Feature is enabled AND user has access; continue happy path...
How do feature flags work?
Most feature flag implementations have two primary components:
Flag Definitions: a string ID, e.g. `
analytics
`, and a ruleset that determines the status or value of the flagRule Evaluator: the runtime system that retrieves a flag’s ruleset and evaluates it against the current context, returning the resolved value
A flag is given a definition to determine the flag’s status based on the conditions you define. Implementations vary, but they can all be thought of as conditionals. I’ll use a fake expression language to demonstrate here.
The most basic rule is a static ON or OFF, with no context necessary:
return false;
If you want a feature to be enabled for a subset of users, you might have a flag configured to be ON for users in a certain group or having a certain attribute, and OFF for everyone else:
return user.group IN ['beta'];
Complicated rules can involve a combination of AND and OR conditionals:
return user.group IN ['beta'] AND (customer.isEnterprise === false OR user.volume !== 'high');
When it’s time to check the actual value of a feature flag during code execution, the rule evaluator gets the flag’s definition and evaluates it using the current context.
In the above examples, the current context would include values for the variables `user
` and `customer
`.
Rules and context can be as simple or complicated as your application and business require.
Benefits of Feature Flags
Deploy without causing effects – Isolate changes and explicitly control when effects take place.
Increase business value by segmenting releases – Slowly roll out new, potentially-risky code (canary releases without the deployment complexity). Release a rough draft of a feature to beta users for testing and feedback. A/B test options to determine the best choice.
Separate releasing from deployment – Release features to your users when it makes sense to your business rather than your deployment schedule. A step towards continuous delivery.
Develop faster – By isolating code with feature flags, you can continue to develop around that code before it is fully complete. This enables smaller pull requests and faster code reviews, continuous delivery, and more.
Test easily in multiple environments – No weird branching strategies to determine what environment gets what features.
Test in production – Enable a feature in production for a single internal user to check a weird issue that can’t be replicated.
Trade-offs of Feature Flags
Developer education – Devs may need to be taught feature flag concepts and how to implement them properly.
It’s easy to forget old code – If you are replacing an existing feature with a new version, the old version’s code is no longer needed when the new one is 100% rolled out. Remember to delete the feature flag AND the old code!
Testing multiple paths – If your organization values test coverage (and it should), test BOTH paths of a feature flag, on and off.
Ongoing maintenance – It can be easy to forget what flags are completely rolled out and can be removed. Clean them up regularly and leave everything better than you found it.
Toggling flags can confuse end users – Toggling flags quickly or multiple times may confuse users, as their experience changes randomly.
Implementation Best Practices
Don’t build your own – Use an existing service or library.
Cover both paths – Ensure your code has proper fallbacks for a feature flag being off, whether that’s reverting to the existing feature or displaying a message to the user.
Cover broad areas – Feature flags should cover large chunks of code, like an entire feature or endpoint. Don’t be granular and cover a single function or component.
Use consistent naming – Whatever standard you choose for feature flag naming, keep it constant.
Make deleting flags easy – Separate the code for the old path and use early return patterns, so removing the flag means only deleting code:
public function analytics() {
if (featureEnabled('newAnalytics') === false) {
this.analyticsOld();
}
// New analytics implementation...
}
private function analyticsOld() {
// Original analytics implementation...
}
When the feature flag is rolled out 100% and we’re ready to remove the code, we can delete the IF conditional and analyticsOld implementation, leaving the new implementation untouched.
How Seniors Approach Feature Flags
They identify a need first – Seniors identify shortcomings in the projects, practices, and business, and find solutions proactively. Consider adding feature flags to your code base if you’re dealing with one of these problems:
Deployed code often has a negative side effect and needs to be rolled back or fixed immediately
Pull requests are large, hard to code review, and aren’t merged quickly enough
A feature is complete but can’t be deployed because another team (like Marketing) isn’t ready yet
You want to test a feature in an environment outside of local dev, but your git arrangement for that is complicated
The business isn’t sure if they should use option A or B
They understand the trade-offs – Like any new addition to your codebase, feature flags come with a cost of proper implementation, maintenance, and possibly performance. Understand the pros and cons and make decisions and adjustments accordingly.
They don’t build their own implementation – Unless absolutely necessary, save time and effort by using an existing solution.
They standardize and document – Make sure everyone around you has the resources to learn and use flags also.
They stay on top of maintenance – Don’t introduce something you aren’t willing to own and take care of.
They make engineering faster and more reliable – Feature flags offer a lot of benefits for both developers and the business as a whole. Their wins are your wins!
👋🏼 Always a pleasure to have you here, Seniors! Talk again soon.
Aken 💙