Fun with Flags I

A Brief Introduction to Feature Flags

A simple yet powerful concept that has probably existed since the dawn of software, gaining strength with the introduction of Continuous Delivery and A/B Testing in the last decade. Configurable “code paths” allow for easy switching between versions of our program, enabling two (or more) alternative functionalities to coexist, which can be selected simply by modifying a parameter located elsewhere in the system. This parameter can be part of the code, managed as an environment variable during deployment, stored in a database and accessible from a configuration interface, or even reside in an external service (either within the system itself or provided by a third party).

I’m not going to reinvent the wheel by trying to explain in depth something that can be found in (at least) two free books promoted by leading platforms in the management of feature flags. I have read them, and they have guided me in working with them over the past few years. I invite you to download and read them.

What I will do next is briefly comment on some very important points that, in my experience, are worth considering when working with feature flags.

Complexity

One detail to keep in mind when starting to add feature flags to our system is the additional complexity. Each feature flag introduces a new dimension in the possible state space of the system. With two flags, for example, there are four possible combinations (enabled/enabled, enabled/disabled, disabled/enabled, and disabled/disabled). This space grows exponentially with the number of flags, as each one doubles the number of possible combinations.

These combinations are, of course, states of the system as a whole that will normally go unnoticed when we add our feature flag in a specific part that is simple to manage separately. However, when taken together, they can quickly become a challenge for the QA of the entire system. If we add multiple teams responsible for different flags in their domains, or worse yet, in shared domains where the outcome of the flags indirectly affects other parts of the system, we may find ourselves in a rather delicate scenario.

Therefore, it is very important to consider, before we begin adding feature flags, what the impact on increasing entropy will be. Although it may seem counterintuitive, since we are adding “control points,” we will disorder our system in a way that can easily slip out of our hands. Here are some points to consider to mitigate the negative effect that flags may have on our system:

Maintenance

I have already discussed the importance of limiting the lifespan of flags. Each time we add one, we are adding a refactoring task to remove it in the future. It is crucial to schedule these tasks when introducing flags and to design the code in a way that makes it as straightforward as possible to eliminate them. Let’s remember the SOLID principle of open/closed (OCP): our classes dependent on feature flags should be closed for modification and open for extension.

To apply OCP when working with feature flags, you can follow these practices:

When feature flags become unnecessary, they turn into technical debt, which increases the likelihood of errors, complicates code refactoring, and, as mentioned earlier, raises the risk of unexpected interactions. Additionally, a poorly documented flag poses a danger, as it could be reused or expanded in a way that deviates from its original intent, and this change could go unnoticed. Therefore, it is essential to follow a rigorous expiration strategy to preserve the integrity of the system.

Tips for Mitigating Technical Debt with an Expiration Strategy:

Strategy

It is important to understand what you want to achieve by using feature flags. Is it a tool to facilitate continuous deployment in our system, allowing us to decide when to make a feature release effective? Or is it a means to experiment with different versions before choosing one? Is it a safeguard method to quickly deactivate sensitive parts and mitigate disasters? This planning is part of a strategy, and it is essential to define it beforehand to properly classify and manage our flags.

Feature flags are deferred decisions, and if used deliberately as part of a plan, they can be a good idea. However, if we are uncertain about what we want to achieve or how to measure the impact of our decisions from the outset, it is better to clarify these points. What may seem like an advantage now could become a trap in the future.

In the previous points, we mentioned practices for defining a good strategy; however, it is important to emphasize the necessity of defining the objective of each feature flag. Before creating a flag, clearly establish its purpose and what is expected to be achieved with it, whether it is a gradual deployment, an experimentation phase, or a safeguard. It is also essential to set metrics to measure the impact of each flag; this involves defining key indicators that will allow you to evaluate if the flag is meeting its objective, such as performance, error rates, or user feedback.


When you have a hammer, everything looks like a nail. Feature flags are a very powerful hammer, so before filling your system with them, keep in mind that “with great power comes great responsibility,” and that a hammer can ruin your grandmother’s precious kitchen tiles.

<< back to list