The single biggest value add of feature flags is that they de-risk deployment. They make it less frightening and difficult to turn features on and off, which means you'll do it more often. This means you can build more confidently and learn faster from what you build. That's worth <i>a lot</i>.<p>I think there's a reasonable middle ground-point between having feature flags in a JSON file that you have to redeploy to change and using an (often expensive) feature flags as a service platform: roll your own simple system.<p>A relational database lookup against primary keys in a table with a dozen records is effectively free. Heck, load the entire collection at the start of each request - through a short lived cache if your profiling says that would help.<p>Once you start getting more complicated (flags enabled for specific users etc) you should consider build-vs-buy more seriously, but for the most basic version you really can have no-deploy-changes at minimal cost with minimal effort.<p>There are probably good open source libraries you can use here too, though I haven't gone looking for any in the last five years.
The call out on premature optimization is valid. However this article misses the mark on a couple fronts.<p>One, as others have called out, is the ability to control rollout (and rollback) without needing a deployment. Think mobile apps and the rollout friction. If something goes wrong, you need a way to turn off the offending functionality quickly without having to go through another deployment or a mobile app review.<p>Second, is to be able to understand the impact of the rollout. Feature flags can easily measure how the rollout of one feature can affect the rest of the system - whether it is usage, crash rates, engagement, or further down the funnel, revenue. It’s a cheat code for quickly turning every rollout into an experiment. And you don’t need a large sample size for catching some of these.<p>By having this power, you will find yourself doing more of it, which I believe is good.
If you have enough traffic then you’ll want to roll out new features gradually, and revert them quickly if despite your testing it causes trouble in production.<p>If you don’t have much traffic, and can live with having to redeploy to flip the switch, then fine, stick it in a config file.<p>But I clicked through expecting a defence of hard coding feature flags in the source code (`if true` or `if customerEmail.endsWith(“@importantcustomer.com”)`). I very don’t approve of this.
One sense of feature flag that I am familiar with (not from experience) is in trunk based development where they are used to integrate new code (with a feature flag) which is relatively untested. Or just not fully developed. That’s an alternative to longer-lived feature branches which are only merged until it is either fully finished or (going further) fully tested. Hard-coding that kind of feature flag makes sense. Because a later revision will delete the feature flags outright (removing the branches).<p>There also seems to be <i>feature flags</i> in the sense of toggling on and off features. Then hard-coding makes less sense.
I've had an issue with gitlab feature flags when gitlab became unavailable. I couldn't fire a new deploy and the system wouldn't work until gitlab came back to life.<p>That was a stupid dependency.
It's even okay to hardcode them into code (not a config/json file). Depending on the build pipeline this is similar to preprocessor flags, and the code will be removed during build.<p>It might be enough to test new features with a limited audience (beta build, test deployments for stakeholders/qa).<p>If done correctly this solution can be easily extended to use a feature flag management tool, or a config file.<p>PS: removing new features during build/tree-shaking/etc adds some additional security. In some cases even disabled features could pose a security risk. Disabled features are often not perfectly tested yet.
My team just had an issue where a new feature caused our live app to grind to a halt. One of the key reasons it took so long to fix is that the dev in charge of the feature had removed the remote feature flag earlier that day.<p>Redeploying takes time. Sometimes you want to disable something quick. Having a way to disable that feature without deploys is amazing in those cases.<p>That being said, there’s really no need to rely for a dedicated service for this. We use our in house crm, but we also have amplitude for more complex cases (like progressive rollout)
There is something too this, though jumping all the way to DIY is unnecessary.<p>Context: I run a FF company (<a href="https://prefab.cloud/" rel="nofollow">https://prefab.cloud/</a>)<p>There are multiple distinct benefits to be had from feature flagging. Because it's the "normal" path, most FF products bundle them all together, but it's useful to split them out.<p>- The code / libraries for evaluating rules.
- The UI for creating rules, targeting & roll outs.
- The infrastructure for hosting the flags and providing real-time updates.
- Evaluation tracking / debugging to help you verify what's happening.<p>If you don't need #1 and #2 there, you might decide to DIY and build it yourself, but I think you shouldn't have to. Most feature flag tools today are usable in an offline mode. For Prefab it is: <a href="https://docs.prefab.cloud/docs/how-tos/offline-mode" rel="nofollow">https://docs.prefab.cloud/docs/how-tos/offline-mode</a> You can just do a CLI command to download the flags. Then boot the client off a downloaded file. With our pricing model that's totally free because we're really hardly doing anything for you. Most people use this functionality for CI environments, but I think it's a reasonable way to go for some orgs. It has 100% reliability and that's tough to beat.<p>You can do that if you DIY too, but there's so many nice to haves in actually having a tool / UI that has put some effort into it that I would encourage people not to go down that route.
There's a typo in the article:<p>>Hardoced feature flags<p>Think the author obviously meant "hardcoded" here.<p>Anyways, recently, this has been really hard to sell teams on in my experience. At some point "feature flag" became equivalent to having an entire SaaS platform involved (even for systems where interacting with another SaaS platform makes little sense). I can't help but wonder if this problem is "caused" by the up-coming generation of developers' lived experience with everything always being "online" or having an external service for everything.<p>In my opinion, your feature flag "system" (at least in aggregate) needs to be layered. Almost to act as "release valves."<p>Some rules or practices I do:<p>* Environment variables (however you want to define or source them) can and should act as feature flags.<p>* Feature flag your feature flag systems. Use an environment variable (or other sourced metadata, even an HTTP header) to control where your program is reading from.<p>* The environment variables should take both take priority if they're defined AND act as a fallback in case of detected or known service disruption with more configurable feature flag systems (such as an internal DB or another SaaS platform).<p>* Log the hell out of feature flags, telemetry will keep things clean (how often flags are read, and how often they're changed).<p>* Categorize your feature flags. Is this a "behavioral" feature flag or functional (i.e., to help keep the system stable). Use whatever qualifiers make sense for your team and system.<p>* Remove "safety" flags for new features/releases after you have enough data to prove the release is stable.<p>* Remove unused "behavior" flags once a year.<p>My $0.02
Just put your flags in environment variables.<p>Depending on your infra, that can already make them toggleable without a redeployment: a restart of the apps/containers on the new envvars is enough.<p>Having them in a separate file would be useful if you need to be able to reload the flags upon receiving SIGUSR1 or something.
> Simply start with a simple JSON file, read it in at application startup,<p>That's not what I'd call hardcoding, it's a startup-time configuration option. Hardcoding is, well, "hard coding", as in changing something in the source code of the affected component, in particular with compiled languages (with interpreted languages it the distinction is a bit mushy.)<p>And then for compilation there is the question whether it is a build system option (with some kind of build user interface) or "actual" hardcoding buried somewhere.<p>Also, there is a connection to be drawn here to loadable/optional software components. Loading or not loading something can be implemented both as startup-time or runtime decision.
I have found feature flagged rollouts to be one of the biggest advances in fairly recent software development. Probably too much to say about it in a comment, but they massively de-risk launches in a number of important ways, both in being able to quickly turn a feature off if it has unintended consequences and being able to turn it on for a very specific set of users.<p>With that said, I think that LaunchDarkly and the like are a bit expensive and heavyweight for many orgs, and leaving too many feature flags lying around can become serious debt. It totally makes sense to start with something lighter weight, e.g. an env var or a quick homegrown feature in ActiveAdmin.
Sometimes the flag management is more complex than dealign with config - but it's not ideal. Hardcoding flags can be difficult to manage across different environments, regions, customers, etc. Atono.io has flags built right into the stories and it's free for up to 5 users. No limits on the number of flags. Also helps with planning, and bug tracking. Keeps things nice and tidy.
I built a Ruby library for feature flags that’s completely hardcoded.<p>In a rails app you have an ./app/plans folder with Ruby files, each command containing a class that represents each feature in a plan.<p>There’s code examples at <a href="https://github.com/rubymonolith/featureomatic">https://github.com/rubymonolith/featureomatic</a> if you want to have a look.<p>I’ve used it for a few apps now and it’s been pretty useful. When you do need plug a database into it, you can do so by having the class return the values from a database.
It seems like the more deployment friction there is for your project, the more the scale tips toward buy vs build here.<p>As a solo dev, something lightweight and cost-effective like this is attractive. Deployment is a CLI command or PR merge away.<p>Would I recommend it for the 200 person engineering org that deploys at most once a week? Probably not.
The whole point is to reduce the risk of the deployments by easily managing the flags - often without the need for a developer. Also, using services like Azure App Configuration gives you the possibility to have different distribution based on users, groups, country etc, which is a really useful.<p>A bit surprised people rolls their own implementation when this is easily available, and not that expensive. At least in Azure.
This statement is not true if your organization has very stringent deployment requirements or a release cycle that is measured in days rather than hours. If you can go from idea to deployment in under an hour, sure, you probably don’t need a fancy feature flag system. That’s not the case for a lot of organizations. Source: spent a really long time fixing agony caused by hardcoded feature flags.
If I may make an suggestion: Instead of a static json file, read at boot, I'd suggest passing the feature flags down per request as a header, or a pointer to the set of feature flag. So that all systems for a given request, observe the same features. Just my 2 cents.
A reason to use feature flag third party services is for the analytics and insights into the user behaviour. Such services cost a lot but might be worth it if you don't have the resources to build such an infrastructure.
Hard-coded feature flags are more commonly referred to as configuration.<p>The primary purpose of feature flags is to provide a way to change system behavior dynamically, without needing a deploy.
An area where hardcoding may not work is when multiple teams and services have to turn something on or off. It is much better to have something external.
1. It's ok if deployment is quick and no customers are affected, but if you're running something like a whitelabel fast food app platform with a deployment cycle that takes a minute, that's enough time to get irate customers
2. The author obviously doesn't understand the importance of flags for new features which may break the customer experience when they dumb it down to the color of a button. I stopped wasting my time reading when I got there.