A guide outlining the steps that should be taken when it comes to sunsetting features
In this part of our series, we will be looking at the different ways feature flags can be stored based on which category they belong to.
Let’s start with a simple definition of feature flags. A feature flag is a software development practice that allows you to decouple code deployment from release, enabling quicker and safer releases.
They allow you to enable or disable functionality remotely without changing code. At its most basic, a feature flag is a file separate from your code file.
For a more comprehensive overview of feature flags, read our definitive guide to feature flags.
You could start off deploying feature flags using a configuration file. This is the simplest implementation method. A config file is usually used to store application settings and some flags just fall into this category.
However, this might be time-consuming as developers may need to redeploy the application after each value update to reflect the changed value. Redeploying can take some time and if your changes are mission critical you may lose some reactivity. Configuration files also don’t allow you to make context-specific decisions, meaning that flags will either be on or off for all users (only hold one specific value at a time).
This makes the most sense when you’re just starting out your feature flag journey and you wish to experiment with feature flags at a smaller scale. Additionally, this could be a viable option for static flags like a release toggle, which are feature flags that enable trunk-based development to support dev teams as they write new features.
For example, a developer may need for a kill switch to work instantaneously to kill off a buggy feature while the flipping time for a release toggle from off to on can take longer.
Such static flags, as their name implies, will be relatively static and will only change through code or configuration file changes.
To better understand how feature flag values should be stored, it’s best to start with the different categories of flags, which are based on longevity and dynamism.
Short vs long lived flags
Longevity of a feature flag, as the name suggests, refers to how long a flag will remain in your code.
Some types of flags are short-lived such as release toggles while others such as kill switches are long-lived; they will stay in your codebase often for years.
This distinction between short- and long-lived flags will influence how you go about implementing its toggle point. The longer the lifetime of a flag, the more careful you’ll need to be in choosing about choosing the toggle point location.
Keep reading: Short vs Long-lived Feature Flags (Fun with Flag series)
Dynamic vs static flags
There are obviously different types of flags, which means these different flags cannot be managed and configured the same way. Dynamism refers to how much we need to modify a flag in its lifetime.
Therefore, feature flags can be broken down into two categories depending on how they are hosted:
- Static flags-as already mentioned, these are usually hosted by a file that only changes when you want it to. These flags get hard-coded into the app at build time so the flag configuration is stored in the actual code.
- Dynamic flags-usually hosted by a service that will change the value of the flag depending on the values you send with the request. This type of flag can be changed at runtime allowing for dynamic control of code execution on a user-by-user or session-by-session basis.
This means that the configuration for some types of flags needs to be more dynamic than others. For example, if you want to change a value based on a shared attribute among groups of users.
Alternative storage method: database
As an alternative to config files, feature flags can be stored in some sort of database. It is a convenient place to store your settings and they can often be easily updated.
So if you see the number of flags in your system and you need more granular controls, you might opt to deploy your flags via a database. This would allow you to target features to individual users.
Moreover, having flags in a database means that not only your developers can change values assigned to flags but also your product teams, thereby reducing dependency. This assumes that some kind of dashboard or management system is in place for other people to easily interact with the database. You’ll also probably want to keep track of changes to this database.
However, you still wouldn’t be able to do gradual rollouts or targeting users based on IDs or attributes or monitor metrics. In other words, it limits the extent of your user segmetting.
Consequently, while config files and databases are quick solutions, when you’re just starting out, they are not good in the long-term if you’re looking to scale or use more dynamic flags.
You might then consider a feature flag open source solution, which allows for simple user segmentation and controlled rollouts. Nevertheless, such solutions wouldn’t allow you to track who made changes or limit access and they are generally language specific. This could be a problem if your application uses multiple languages so you would need to deploy multiple solutions.
Feature management services
The most dynamic flags are those whose state depends on the current user. Dynamic flags need to be hosted by a service rather than a static file mentioned previously. This is because feature flag services allow you to serve different values to different types of users at runtime.
In that sense, you would target values based on user IDs or according to percentage, i.e. a feature can be seen by x% of users, or according to a certain group the users belong to, using some user traits as targeting criteria.
This also works if you’re experimenting with features, with a traditional A/B testing approach, and you need to randomly put users in different groups so the user’s ID would be sent to the service to place in a group accordingly.
Such IDs (that could be stored in cookies or localStorage…) are also useful when testing internally where a feature is turned on for internal users as detected via a special ID value. Developers would then turn these features on for themselves to make sure it’s working as it should and test directly in production.
In such situations, you would opt for a third party service to fetch values of the feature flags.
Such feature flag services would, therefore, also allow you to to choose values for each flag depending on specific attributes such as the country users are from.
For example, Flagship by AB Tasty allows you to assign specific flag values to different user segments. So, internal users would be served one value and would then see the new feature while external users will be served another value.
For example, in the image below from the Flagship dashboard, the value that is fetched will be IOS in Scenario 1 and ANDROID in Scenario 2 so only the users matching this value will be exposed to the feature.
This is extremely useful if you want to do gradual rollouts and testing in production and for generally more advanced use-cases.
For advanced use-cases, it would make sense to opt for a third party solution to help you manage and implement the different types of flags in your system.
These solutions offer features such as a UI for managing configuration with access control to limit who does what as well as audit logs to determine which changes were made by whom.
Therefore, sophisticated feature management solutions like Flagship are built to scale and include role-based and access controls to execute more complex use-cases.