You're reading the free online version of this book. If you'd like to support me, please considering purchasing the e-book.
Types of Feature Flags
Feature flags vary in both the type of variants that they serve and in the way they're expected to operate within your application. Short-lived, Boolean-based features flags are likely to be the first type that you use. Their on/off state is easy to reason about; and, it closely aligns with the if
statements that we already use in our application control flow. But, feature flags can be used—and abused—in many different ways.
Data Types
Any type of data that can be serialized for storage can be used in a feature flag. We think about feature flags as being a runtime concern—and they are primarily; but, they also have to be persisted across application restarts and sent over the wire. As such, we can only use data that is capable of being serialized and deserialized without the loss of information.
It's helpful to think of variant data as anything that can be represented as JSON. Data types such as strings, numbers, Booleans, objects, and arrays will therefore work naturally as a variant value since they each have native representations in JSON. Other data types such a date/time values can still be used; but, they will need to be translated (within your application code) into and out of JSON-compatible data-types.
Conceptual Types
Feature flags fall into two conceptual types. Mechanically, these two types are exactly the same—they differ only in how long they are intended to remain embedded within your application logic. I call these two types:
- Product: relatively short-lived feature flags.
- Operations: long-lived (possibly forever) feature flags.
These are the terms that I use personally - they are not industry standards.
A product feature flag is intended to be used during the development of a new product feature. And, when said feature is enabled for all customers (and has had time to bake in production), this feature flag should be removed from the application. Product feature flags should have a finite timeline.
Operations feature flags, on the other hand, are tied to the ongoing operation of the application itself and have no inherent timeline. The log level feature flag that we discussed earlier is the perfect example of an operational feature flag—it will continue to add value for as long as the application is generating log entries. As such, there is no intention to remove this feature flag from the code.
Given that these two conceptual types are mechanically identical, the value-add in this classification comes down to developer ergonomics. Feature flags add complexity to a codebase. As such, it's paramount that we do everything that we can in order to keep the code easy to understand.
To this end, I strongly encourage you to create divergent naming patterns for product feature flags and operations feature flags. This way, when a developer is looking at the code, it becomes immediately clear as to the intended role of a given feature flag.
I've taken to prefixing my product feature flags with product-
and my operations feature flags with OPERATIONS-
. Furthermore, my product feature flags are also infixed with a ticket number such that I can easily tie a feature back to an epic or user story.
A product feature flag that represents a new checkout process might be named:
product-GROWTH-1234-checkout-process
... where GROWTH-1234
is the corresponding ticket number.
An operations feature flag that represents log level aggregation settings might be named:
OPERATIONS-minimum-log-level
This simple naming convention can go a long way in terms of reducing the cognitive load imposed on the people working in the product. It can also make it clear which feature flags are intended to be there; and, which feature flags may be forgotten relics, begging for removal and simplification.
Note: For the sake of brevity, I do not follow this naming convention in all of my examples in this book.
Since this classification represents an arbitrary difference, not a technical one, I find it helpful to consider the consumer of the feature flag. If the intended consumer of the feature flag is the user—and, enabling the feature flag will alter the user experience in some way—it's a "product" feature flag. If, however, the intended consumer is the application, it's an "operations" feature flag (even if that sometimes means a user experience will be affected as a byproduct of feature flag state).
Sometimes, a "product" feature flag will never be released to 100% of users; and, therefore, will never be removed from the application. In such a scenario, I still consider the feature flag to be of the "product" type; especially if future removal of the targeted users could one day merit removal of the feature flag.
Have questions? Let's discuss this chapter: https://bennadel.com/go/4546
Copyright © 2025 Ben Nadel. All rights reserved. No portion of this book may be reproduced in any form without prior permission from the copyright owner of this book.