In the world of apps, bugs happen — even with the best developers and rigorous testing techniques. So, imagine this: you and your team have just released a new feature to your mobile app and are excited for your users to try it out. Unfortunately, things don't go the way you thought they would. An unexpected bug slipped into production, and now things are crashing. You have two options: either deploy a fix immediately or revert the feature.
There's just one problem: deploying mobile apps is not as straightforward as deploying web apps. It takes anything from hours to days to release a new app version or updates to apps stores. App stores have to review and approve updates before you can deploy them into production. For iOS, manual reviews happen for all apps, taking 24-48 hours to complete. On Android, manual reviews do not always happen, but they can take more than seven days when they do.
But you can't wait that long when there are bugs, as you risk losing users. You have to do something immediately. That's where feature flags come in. Feature flags allow mobile engineering teams to disable features instantly without having to go through the app store. Here, we'll take a look at what feature flags are, how they work, when it makes sense to use them, and the various ways to implement feature flags in a mobile development workflow.
What are feature flags?
From a high level, feature flags (otherwise known as feature toggles or feature flippers) are basically configuration variables used to either enable or disable a feature. The code that enables the feature in question will be wrapped in a conditional statement that depends on the variable's value. E.g.:
The variable can either be stored locally or remotely. For most use cases, such variables (the feature flags) are stored outside the codebase, so developers can update their app without deploying new code or needing users to download an app update. If the condition is false, that code path is not traveled, and that feature won't be enabled. If it is, the code path is crossed, and the feature will work.
For example, imagine your team is building a machine learning/AI-powered chatbot as an alternative to your app's existing live chatbox. But you're not sure if it'll meet the needs of your users effectively or even how they'll react to it. You can use feature flags to introduce the functionality:
Now you and your team can update the flag variable whenever you want to either enable or disable the new chatbot, based on how users perceive it.
The example above is the most basic form of feature flags. A feature flag can have percentages or segments and get as complex as needed to help manage features per team, per user, per app version, or whatever is required.
With feature flagging, mobile developers, product managers, release managers, and even customer account officers on your team can:
- Have a feature kill switch: When things don't go as planned with a feature in production, you can use feature flags to disable the feature till your engineering team can figure out what went wrong.
- Safely test in production: Feature flags offer a less risky way to test on real, live end-users in production. You can gradually roll out features to a subset of users so you can obtain valuable feedback before releasing the feature to the rest of your users.
- Separate code deployment from release: For features that will take time to complete, instead of creating a long-living feature branch then struggling with merge hell, later on, you can use feature flags to push and deploy your code changes to production without affecting any existing functionality. The feature can then be activated whenever it is ready.
Common use cases for feature flags in mobile development
Feature flags are helpful for numerous scenarios typical with mobile development teams.
- Product and marketing campaigns: Mobile development teams can use feature flags to separate the code deployment from the feature release. Then, product and marketing teams can safely roll out features when they are ready. For example, grant access to a feature to a group of elite users or new users to drive signups or do a timed release to build up anticipation and also drive signups.
- A/B testing: Feature flags can be used to activate different experiences for subsets of users. You can, for example, divide your user base into three sections. Each section will receive a different version of a feature. The performance of these three features will then be compared to determine which should be chosen. You'll be able to find out which a/b test feature has the higher product conversions, engagement, growth, subscription rates, or revenue.
- Subscription management: Multivariate feature flags can be used to manage the suite of features different customers in different subscription levels should have access to.
- Opt-in early access campaigns: You can allow users to opt-in for early access to new features to consciously help you test out the features and provide feedback. In return, the user gets some cool benefits. Google Labs is an example.
Complexities associated with feature flags
Using feature flags is not all rosy and simple. Yes, they primarily help mitigate risk, but they could also turn out to be risky themselves. You should try not to use them haphazardly, or you may end up with a codebase and delivery pipeline more complicated than it needs to be. You need to be aware of the challenges associated with using feature flags to optimize their use:
- Increased technical debt: If stale, unused flags remain in your codebase, this would eventually accumulate technical debt because you have to keep maintaining them. That's why it's essential to clean up flags once they are no longer active.
- Code complexity: The build-up of feature flags in your system can lead to messy code over time. When two or more feature flags are combined, the complexity and possible combinations of the app state can grow exponentially.
- Testing complexity: A feature flag splits your code paths into two or sometimes more. This means you'll have that many more paths to test.
Best practices for designing feature flags
Adhering to a few best practices when using feature flags could save you a lot of pain and avoid some of the complexities mentioned above.
- Use a sensible naming convention: In the absence of a naming convention, team members may end up naming flags with the same name and getting flags jumbled up. As a result, a team member may activate the wrong flag, potentially causing system interruptions. Defining a name or naming convention for your flags is one essential way to keep all the different flags you have in your system organized and unique. Your feature flag naming convention should be as descriptive as possible and include things like your team's name, date of creating the flag, description of the flag's behavior, and flag category (temporary or permanent). For example, if you want to name a new chatbot feature for your mobile app, you may name it something like AITeam_17-08-21_chatbot_test.
- Control access to feature flags: Every flag should have an owner — someone who should be able to answer why the flag is needed and be responsible for removing it. If there's no one like that, the feature flag can become stale and unmaintained, leading to technical debt.
- Feature toggles should have a limited life span: Unless a feature flag is a permanent part of a system (e.g., app upgrade or version flags), you need to remember to delete feature flags when they’re no longer in use or the feature changes.
- Watch out for feature flags that are dependent on one another and conflicting feature flags: Feature flags can become an issue as the development team grows. Take for example, two teams: TeamA and TeamB are building their respective features, behind FlagA and FlagB. They both test that this feature works when their flag is turned on. However, they are unaware of the other team building their feature and so do not test it with that flag switched on. During rollout, when both FlagA and FlagB are turned on, a part of the app breaks. Mapping out feature flags dependencies as part of rollout plans is how most teams solve this problem.
How to implement feature flags in mobile development
There are many paths to implement feature flags with varying logistical considerations and return on investment. The path you take will depend on your team's needs, level of complexity, and organizational goals:
- Config files: You can use configuration files such as iOS .plist file or .env file to store flag values and then their values used within if/else statements directly in your code. This is the simplest and often the starting point for most teams.
- Database configs: You can store flag settings in a database. It’s a pretty common and convenient place to store your settings as they can be updated easily using an administration interface.
- Open-source libraries: There are several open-source libraries for feature flags management. However, installation and maintenance are often the biggest challenges with such libraries (or even proprietary solutions). Some examples are Featurehub and Unleash.
- Third-party services: For more advanced use cases, you may need more complex third-party feature flag management tools like LaunchDarkly, Optimizely, Firebase Remote Config, or ConfigCat.
Optimize mobile deployment with feature flags
Using feature flags enables mobile teams to ship features more often, minimize risk, increase productivity, and even help with targeting users and A/B testing features.
There are also other processes companies can adopt to optimize mobile deployments. But one of the most critical is having a reliable CI/CD pipeline using a mobile-focused CI/CD tool like Bitrise.
- Feature Flags — A successful architecture by Jeron Mols, Google Developer Expert