Rendered at 08:05:28 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
jameshart 20 hours ago [-]
In my experience these (configuration based feature flags and feature flag services) are actually two complimentary capabilities that solve two completely different problems but that happen to share the same name: feature flags.
The config approach is critical for using feature flags as a software development lifecycle tool. It is how you manage having a codebase which contains the unfinished code for new feature x, but can still be deployed and pass all tests without feature x being turned on.
In this model you need a mechanism which allows a developer who is working on feature x to enable it for local testing, and for your CI system to be able to interact with the flag system to test that the application works in both states - with x turned on and off.
This is ideal for trunk based development models; feature branches are an alternative approach that doesn’t really benefit from this (indeed it adds complexity to working in feature branches).
Meanwhile feature flag services are to solve the problem that different people using the same software need different features turned on. That can be as simple as internal testers or beta users, it can be holding features to roll out in fixed update windows per tenant, or it can be part of a risk management strategy where features are rolled out through progressive exposure.
It can also be tempting to mix up your feature flags system with an A/B testing system - you can use a feature flag service to expose a feature to a test cohort and measure performance changes.
There can be reasons for doing that but it’s really important not to tie all these things together: not every development lifecycle change is an ab test hypothesis. Not every ab test hypothesis is a development lifecycle change (often it is really about testing changes in data, and feature config is just one piece of data you might want to change). Similarly some other data changes than code changes need to roll out progressively to mitigate risk.
So all these things might be feature-flag shaped, but that doesn’t mean you can substitute different feature flag solutions in and solve the same problems.
This post is saying ‘it’s okay not to have an exposure control solution; you can have a config file’ - which is obviously true, if what you have is a config management problem, not an exposure control problem.
jdwyah 20 hours ago [-]
Strongly agree that Config & FeatureFlags are two different things. But as I've tried building tools in the space: man is it difficult to really nail down what the difference is.
For Quonfig I landed on:
- Data model wise they are identical. Flags and configs can both be targeted. They can both use segments. They can both do partial rollouts. They can both have the same range of values (bool/number/duration/json/json-w-schema/etc)
- Its fine to use Flags for your Experiments/AB Tests, but that's just the "allocation engine". The rest of experimentation is the exposure tracking and goal tracking. Those ought live in your product analytics stack, because they are really just events. But its helpful to have a single place (flags) for the experiment allocation because then you can re-use segments for things like hold out groups / and just general targeting.
- The only real difference is that Flags are intended to be ephemeral and configs are intended to be permanent. A good UI should show you how long a flag has been alive and help you clean it up (or convert it to a config) if it's been true for everyone for too long.
- The use cases are different enough that it's worth keeping them in two separate UI.
scott_w 18 hours ago [-]
One way I’ve thought of it is to ask what happens if the function is blocked, how is it enabled mechanically and why would that be changed? Once you answer these, you start to see the groupings more clearly, I’ve found.
scott_w 18 hours ago [-]
I 100% agree with everything you said and more. I spent a significant amount of time at my job arguing constantly with the entire engineering department that “Feature Flags” are not all the same thing and had to push back on efforts to mix them all up.
Examples:
Experiment flags for A/B testing
Permission checks at a user level
Product flags for feature gating by plan
Rollout flags to launch a new feature gradually
Configuration for an account/system/feature
The number of times I had to push against the “just put it behind hasFeatureFlag(user, flag)” is more than I can count at this point! I think it comes from a misunderstanding of the DRY principle, to be honest.
jdwyah 14 hours ago [-]
oo yeah.
entitlements is a huge one. Sooooo many orgs are in an absolute rats nest of confusion because half their entitlements are in something like an auth system, half are in something like billing and the third half is hacked into feature flags.
One particular pain point is that finance or something "do users with access to feature X retain better and it's super hard to figure out.
My overall feel is that developers are trying to solve a problem and that it turns out the configuration is as fundamentally as important as the software itself. I define "dynamic configuration" as "a key value store which takes context and has rules based system to give you a value". This primitive turns out to be extraordinarily useful and powerful. Rather than try to split it into N different systems, each custom / don't have telemetry / aren't available to all services SDKs. What if you have ONE BIG CONFIG system that really does a bang up job.
By focussing on one terrific system, you can put all your eggs into the basket of making that reliable / comprehensible / flexible / strict.
The one on your list that I think DOESN'T belong would be permission checks at user level. The N of that is not a good fit for config (though when you look at the facebook paper, it's pretty wild how they've scaled it (but it doesn't do permissions afaik)).
esafak 17 hours ago [-]
Why would you not use the same service to handle them? Less is more.
hasyimibhar 16 hours ago [-]
Having worked at a large company that misuses feature flag service for everything, here are some examples why you shouldn’t:
- one team uses feature flag for product gating. Feature flag service goes down. Users temporarily got locked out of the features they paid for.
- one team uses feature flag for dynamic pricing by leveraging targeting rules (how hard is it to write a bunch of if else in code?). It’s evaluated against all users, even if they are not active (for analysis reasons). Feature flag service charges by MAU. We have millions of users. Our feature flag service bill is now 6 digits per year.
- one team uses feature flag as literal json store instead of a proper db (god knows why). Someone updated the value but the “schema” is wrong. Shit breaks.
esafak 16 hours ago [-]
> - one team uses feature flag for product gating. Feature flag service goes down. Users temporarily got locked out of the features they paid for.
That could happen if they used a separate service. In this case you need to build defaults; open or closed, as the case demands.
> - one team uses feature flag for dynamic pricing by leveraging targeting rules (how hard is it to write a bunch of if else in code?). It’s evaluated against all users, even if they are not active (for analysis reasons). Feature flag service charges by MAU. We have millions of users. Our feature flag service bill is now 6 digits per year.
This is a valid reason if you don't own the service, as it seems you don't. If you did, you should have asked your internal customers what their requirements were.
> - one team uses feature flag as literal json store instead of a proper db (god knows why). Someone updated the value but the “schema” is wrong. Shit breaks.
Separating the services would not help here. They are simply using the wrong tool.
jameshart 15 hours ago [-]
Golden rule of large scale software dev: any system you expose that allows other teams to write text to it will eventually be used by another team as an ad hoc JSON database
scott_w 10 hours ago [-]
I explained: they’re all doing different things, they have different behaviours, they have different performance and uptime characteristics. The reason that the values change are completely different, so how that information is set and read will be completely different. Who sets it, who reads it.
An example: at my current job, we’re using LaunchDarkly for config management, not just rollout. This means an incident on LaunchDarkly didn’t just stop a rollout, it caused the system behaviour to change for a large number of customers as it reverted to the default.
jdwyah 20 hours ago [-]
I am on my second feature flag startup, but I also somewhat agree with this.
Every project should have flags, but many projects need just the basics and a service is overkill.
Rolling your own JSON still feels like something we ought avoid though. Yes to start out it’s 95% booleans. But then you want a rollout. And then you want some targeting rules. And then you want non booleans… maybe some json. Oo wouldn’t it be nice if the json could conform to a schema… and then eventually you are like damn I really want to change these without deploying. Or you want to read the same flag from multiple services.
I’ve tried to incorporate this lowest common denominator into https://quonfig.com Use it totally free & open source as SDK, and it’s just loading JSON that you can track in git. Agents love it, hot reloads, SDK in lots of languages. But vs rolling your own you’ve got a lot of headroom on the design. A bunch of targeting operators. Segments etc. And then if you do want to get a nice UI / delivery network for real time updates, then you can use the paid side of things.
Your second startup dedicated to feature flags? Aren't these just some booleans with optional support to toggle them at runtime? Maybe I've just not been in the right domain, but I would have thought that if someone's use of feature flags is so complicated that they need a whole company to support it then they've massively overengineered their code.
gejose 18 hours ago [-]
The author literally spells out why this isn't always the case:
> Yes to start out it’s 95% booleans. But then you want a rollout. And then you want some targeting rules. And then you want non booleans… maybe some json. Oo wouldn’t it be nice if the json could conform to a schema… and then eventually you are like damn I really want to change these without deploying. Or you want to read the same flag from multiple services.
ambicapter 19 hours ago [-]
Launchdarkly and Statsig are both well-established companies that basically do feature flags+add-ons.
jdwyah 15 hours ago [-]
heh. yes.
First one got acquired. But also I wish I'd built it differently from the start (git based, other lessons learned), so started over.
It's true that it's a pretty simple thing, but you do want them to be of the utmost level of reliability. Its ideal if you can use feature flags & dynamic config (which I think of as the same problem) right at boot time. But then of course you have an external dependency to booting you app. So the reliability angle becomes imperative. So I do think the SaaS can play a good (or bad) role in overall reliability vs something you implement in house.
The other major advantage is telemetry. Once you have things toggling on and off, immediately engineers will get confused about whether something is on or off and why. Basic internal apps usually don't have any good telemetry / debugging. So a good SaaS should give you all kinds of ways to ensure that you can see what context is being passed around to the SDK to do their eval. Sanity checking etc.
My og experience was at HubSpot where we used the hell out of dynamic config. Once you get used to things like instantly targeting debug log levels for a single class to a single org its hard to go back.
aleksiy123 19 hours ago [-]
You can do much more with feature flags like ab testing/experiments, integrations with analytics.
There can be whole UIs and tooling and infrastructure to manage around them and that’s what the sass offer
horizonwingtech 19 hours ago [-]
[flagged]
maxidog 20 hours ago [-]
I’m currently reverse engineering a large enterprise app and the feature flag bloat is truly astounding. Imho excessive feature flag complexity is a symptom of management who are indecisive and mistrusted by the developers.
Gigachad 20 hours ago [-]
You need to be actively deleting them after the feature has gone live
chasd00 16 hours ago [-]
i could see it getting complex with a lot of flags, inevitable you'll run into a situation where more than one flag is combined.
then, down the road, you remove flag4. Hopefully the above would result in a compile error but you may be in a language or situation where a missing flag4 is interpreted as boolean false. That could cause all kinds of havoc in logical combinations like that are scattered all over the codebase. Even worse would be REST APIs retrieving flag values because who knows what's happening in that service code? Plus, you'd never know there was an issue until users start reporting missing or extra features showing up unless you have e2e tests for every possible combination of feature flags...
lpribis 12 hours ago [-]
Surely the commenter means deleting them in the code, not just the management software. Otherwise, what's the point?
You need to find every occurrence of flag4 and remove references to it. So that boolean expression would need to have `&& flag4` removed.
chasd00 10 hours ago [-]
What I’m saying is there may be references you don’t have access to.
forgotaccount3 19 hours ago [-]
Create story to add feature flag controlling access to the feature.
Immediately create story to remove said feature flag controlling access to the feature and review it during backlog refinements.
not_a_bot_4sho 17 hours ago [-]
> Imho excessive feature flag complexity is a symptom of management who are indecisive and mistrusted by the developers.
In my experience, engineers aren't using them to account for managerial dithering, they're doing it for safe deployments and experiments and rollouts and such. A product with millions of users can easily have a tens or even hundreds of active switches at any moment (I'm assuming a large engineering team behind said product), and that's not necessarily a bad thing.
However, as someone else noted here, you absolutely MUST delete and clean up your flags/gates/whatever when you've completed that effort. That part can be tricky because not everyone has the discipline to pay off tech debt.
Usually, a flag/gate should not live in code for more than a few months. If it does, it should have robust justification.
Lucasoato 20 hours ago [-]
This of course depends on the quantity and the depth of these feature flags. It’s ok to hard code few of them, maybe it’s not when it becomes a practice and you have tens of them. I think you would have a much easier life if there was a standardized, well documented, way to define them.
jjice 17 hours ago [-]
The biggest problem I've found with feature flags of this nature (mostly for internal testing and the like) is that they can easily live too long and bloat code. This is also very dependent on what the feature flag on/off code paths do.
1. For reducing outliving, I always create a ticket to remove the flag at the same time it gets added in. This way there's documented work that will get scheduled. YMMV depending on how your team does planning.
2. For flag branch implementations, it's often fine to do an if/else, but I've seen this blow up into a real headache. When I can, I like having two implementations of an interface that get swapped between. Code calls the interface as normal the the underlying implementation is the same. Works for React components and larger implementations/changes that already have an interface. Don't want to force an interface where it feels wrong.
retired 17 hours ago [-]
It might depend on your programming language but what worked for my team was to have a file with all the feature-flags as enums/constants. That way you have a clear view of how many feature flags you currently have in your code and by CTRL+clicking you automatically see all the code associated with that flag.
liampulles 16 hours ago [-]
Like many "cloud native ideas" there is a core 20% to the idea of feature flags that is useful to 80% of teams, and then a remaining 80% of periphery concerns that are relevant to 20% of teams (and I'm erring generously on those figures).
Specifically, the idea of putting toggles on risky functionality is a good idea that is useful broadly. Being able to dynamically toggle feature flags without a restart, or apply some features to some segment of users is unlikely to be useful and entails a lot of complexity and potential footguns.
My approach to feature flags is even simpler than what is suggested here: feature flags are just a section in your config. Done. Even if you are confident that you need more advanced capabilities, you should not "advance" to that level until you have demonstrable proof that your team can manage simple config values for it.
ozim 13 hours ago [-]
I disagree because I have business people to have discussion with different customers on different timelines.
I can't hard code any of the flags until I have big customers notified and onboarded with the change.
So one would say why aren't your customers onboarded with the change before you implement it. Well no because they have 20-30 other applications they are using on daily basis.
While yeah we can push some customers to new features, we still need to have some realistic adoption in place before we can switch ... mostly because we are not Attlasian or Microsoft — we have actual people taking angry calls and angry e-mails from the customers.
alexpotato 18 hours ago [-]
Speaking as a SRE/DevOps guy with almost 20 years of experience:
There are no solutions, only tradeoffs.
I'll give some examples:
Firm 1 had a single server running tron [0] for ALL scheduling of processes.
Pros: very easy to see what should run when and made audits a breeze
Cons: the central server died and it was a giant outage response to make sure that when the server came up it didn't start killing processes that should be running
Firm 2 used a management gui to create custom cron entries on each machine
Pros: each node had a local copy of the schedule and could keep going even if the central system died
Cons: each node had a local copy of the schedule which could "drift" from other nodes, a node could be forgotten etc
So, more generally, I agree that it's good to label things as "ok" so that we don't get into flame wars etc. That being said, the more important point is to say that if you are going to pick a strategy, do the work to support, build tooling and plan for outages related to that strategy.
torginus 17 hours ago [-]
I just wanted to say I haven't been doing C# dev until as of late, and I forgot how flipping amazing the tooling is. One of the things the C# compiler (which is used for IDE tooling) can do out of the box is it can compile multiple versions of the file (syntax, and symbol resolution included), meaning you can still make sure the statically disabled codepaths are still valid, and all the symbols are consistently available in every feature flag combo.
When something does go wrong, the compiler degrades gracefully, and still can make sense of most of the code.
MS gets a lot of flak (sometimes deservedly so), but they can sometimes also show what a large organization of skilled individuals working under consistent direction is capable of.
Pannoniae 15 hours ago [-]
looks like we've circled back to the good old
#ifdef FEATURE_AI_V2
;)
gwbas1c 19 hours ago [-]
> Hardcoded feature flags ... start with a simple JSON file
Any configuration read out of a JSON file is not hardcoded. Hardcoded means you need to recompile to change it.
(And yes, hardcoded, as in flags set with #define or equivalent, are totally fine depending on what you're doing.)
odyssey7 19 hours ago [-]
Depends on how you deploy. If changing it in prod requires a PR merge and a release approval, I’d consider that pretty hardcoded.
kalcode 19 hours ago [-]
That's a bit too rigid of a definition. Just means it requires a code update to change it, that's hardcoded.
jollyllama 15 hours ago [-]
It depends if the JSON file is in source control, or if it's an environment file.
gps372 19 hours ago [-]
Hardcoded feature flags becomes a big issue if your release process is long and error prone. Original article also suggest to enhance incrementally. But you don't want the interval between increments to be too big.
avlcodemonkey 15 hours ago [-]
If you're working with C#, Microsoft added first class support for feature management in .Net with https://github.com/microsoft/featuremanagement-dotnet. It provides the logic for simple on/off, user targeting, percentage roll outs, and schedules. Using feature management along with flags hardcoded in `appSettings.json` makes perfect sense for a simpler application.
When your architecture grows and you start needing to synchronize configuration across multiple applications, or have non-technical users change flags, then you've probably outgrown hardcoding and need to consider building (or buying) a service. You probably don't want product owners trying to set an env var like `FeatureManagement__NewFeature__EnabledFor__0__Name`. Azure App Configuration is the go to if you're willing to use Azure - it provides a nice UI for editing flags instead of dealing with JSON. Or, I've been building https://featureflags.app/ as an alternative provider if you prefer to steer clear of Azure. Its kinda the middle ground between hard coding and a full on platform like LaunchDarkly.
aksappy 20 hours ago [-]
Unclear how the arguments against feature flags can be used to justify hardcoding them or using a JSON file to manage them. Feature flag decisions are at the end of the day, tradeoffs to solve a problem that may occur for another person at a different place/time. If you are a solo developer, hardcode, use bytes or mail your feature flags - it does not matter. If you are not, there is a lot to take care of beyond a single hardcoded json file.
cassianoleal 20 hours ago [-]
Why wouldn't it be? The post does a good job explaining why not only it's not a problem, but also likely desirable in many (I'd wager the vast majority) of circumstances.
Simple, effective, cheap, easy to understand and manage. Not dependent on an external service, not dependent on a third-party.
Yep, right up there with Triplebyte back in the day and the drumbeat about "it's so hard to bill customers" and "JWT sucks"
drdexebtjl 20 hours ago [-]
To do safe deployments, you must have a way to run versions X and X+1 side by side serving an arbitrary proportion of your users while you inspect metrics.
That covers a lot of uses of feature flags without the bloat.
Xirdus 20 hours ago [-]
Hardcoding feature flags prevents you from deploying the same build with different flag sets side by side and comparing results. Depending on the nature of the project, it might be irrelevant or it might be a deal breaker. Especially in cloud environments, it's usually the latter. And everything is in the cloud nowadays.
jasonjayr 20 hours ago [-]
Do all modern compilers do tree-shaking at this point? Unless you use compiler-based flags, If you hard code them into your code, the dead code paths may still be in the shipped binary. Depending on what you are doing, the security issues mentioned in the article are still present, or you may prematurely reveal an upcoming feature.
andy_ppp 19 hours ago [-]
I've never found feature flag systems complex and you can build one yourself in a few functions. The services I have used in the past were extremely simple to integrate so I don't understand the issue either way honestly.
continuous_lex 2 hours ago [-]
[flagged]
floki165 18 hours ago [-]
[flagged]
michael_luog 21 hours ago [-]
[dead]
devecycle-marke 20 hours ago [-]
[flagged]
mhog_hn 20 hours ago [-]
note that this is a "pre-november 2025 opus 4.5" post folks
The config approach is critical for using feature flags as a software development lifecycle tool. It is how you manage having a codebase which contains the unfinished code for new feature x, but can still be deployed and pass all tests without feature x being turned on.
In this model you need a mechanism which allows a developer who is working on feature x to enable it for local testing, and for your CI system to be able to interact with the flag system to test that the application works in both states - with x turned on and off.
This is ideal for trunk based development models; feature branches are an alternative approach that doesn’t really benefit from this (indeed it adds complexity to working in feature branches).
Meanwhile feature flag services are to solve the problem that different people using the same software need different features turned on. That can be as simple as internal testers or beta users, it can be holding features to roll out in fixed update windows per tenant, or it can be part of a risk management strategy where features are rolled out through progressive exposure.
It can also be tempting to mix up your feature flags system with an A/B testing system - you can use a feature flag service to expose a feature to a test cohort and measure performance changes.
There can be reasons for doing that but it’s really important not to tie all these things together: not every development lifecycle change is an ab test hypothesis. Not every ab test hypothesis is a development lifecycle change (often it is really about testing changes in data, and feature config is just one piece of data you might want to change). Similarly some other data changes than code changes need to roll out progressively to mitigate risk.
So all these things might be feature-flag shaped, but that doesn’t mean you can substitute different feature flag solutions in and solve the same problems.
This post is saying ‘it’s okay not to have an exposure control solution; you can have a config file’ - which is obviously true, if what you have is a config management problem, not an exposure control problem.
For Quonfig I landed on:
- Data model wise they are identical. Flags and configs can both be targeted. They can both use segments. They can both do partial rollouts. They can both have the same range of values (bool/number/duration/json/json-w-schema/etc)
- Its fine to use Flags for your Experiments/AB Tests, but that's just the "allocation engine". The rest of experimentation is the exposure tracking and goal tracking. Those ought live in your product analytics stack, because they are really just events. But its helpful to have a single place (flags) for the experiment allocation because then you can re-use segments for things like hold out groups / and just general targeting.
- The only real difference is that Flags are intended to be ephemeral and configs are intended to be permanent. A good UI should show you how long a flag has been alive and help you clean it up (or convert it to a config) if it's been true for everyone for too long.
- The use cases are different enough that it's worth keeping them in two separate UI.
Examples:
Experiment flags for A/B testing
Permission checks at a user level
Product flags for feature gating by plan
Rollout flags to launch a new feature gradually
Configuration for an account/system/feature
The number of times I had to push against the “just put it behind hasFeatureFlag(user, flag)” is more than I can count at this point! I think it comes from a misunderstanding of the DRY principle, to be honest.
entitlements is a huge one. Sooooo many orgs are in an absolute rats nest of confusion because half their entitlements are in something like an auth system, half are in something like billing and the third half is hacked into feature flags.
One particular pain point is that finance or something "do users with access to feature X retain better and it's super hard to figure out.
My overall feel is that developers are trying to solve a problem and that it turns out the configuration is as fundamentally as important as the software itself. I define "dynamic configuration" as "a key value store which takes context and has rules based system to give you a value". This primitive turns out to be extraordinarily useful and powerful. Rather than try to split it into N different systems, each custom / don't have telemetry / aren't available to all services SDKs. What if you have ONE BIG CONFIG system that really does a bang up job.
(Note: copying the big boys is not always the right move, but https://research.facebook.com/publications/holistic-configur... does give some credence that this is a decent approach)
By focussing on one terrific system, you can put all your eggs into the basket of making that reliable / comprehensible / flexible / strict.
The one on your list that I think DOESN'T belong would be permission checks at user level. The N of that is not a good fit for config (though when you look at the facebook paper, it's pretty wild how they've scaled it (but it doesn't do permissions afaik)).
- one team uses feature flag for product gating. Feature flag service goes down. Users temporarily got locked out of the features they paid for.
- one team uses feature flag for dynamic pricing by leveraging targeting rules (how hard is it to write a bunch of if else in code?). It’s evaluated against all users, even if they are not active (for analysis reasons). Feature flag service charges by MAU. We have millions of users. Our feature flag service bill is now 6 digits per year.
- one team uses feature flag as literal json store instead of a proper db (god knows why). Someone updated the value but the “schema” is wrong. Shit breaks.
That could happen if they used a separate service. In this case you need to build defaults; open or closed, as the case demands.
> - one team uses feature flag for dynamic pricing by leveraging targeting rules (how hard is it to write a bunch of if else in code?). It’s evaluated against all users, even if they are not active (for analysis reasons). Feature flag service charges by MAU. We have millions of users. Our feature flag service bill is now 6 digits per year.
This is a valid reason if you don't own the service, as it seems you don't. If you did, you should have asked your internal customers what their requirements were.
> - one team uses feature flag as literal json store instead of a proper db (god knows why). Someone updated the value but the “schema” is wrong. Shit breaks.
Separating the services would not help here. They are simply using the wrong tool.
An example: at my current job, we’re using LaunchDarkly for config management, not just rollout. This means an incident on LaunchDarkly didn’t just stop a rollout, it caused the system behaviour to change for a large number of customers as it reverted to the default.
Every project should have flags, but many projects need just the basics and a service is overkill.
Rolling your own JSON still feels like something we ought avoid though. Yes to start out it’s 95% booleans. But then you want a rollout. And then you want some targeting rules. And then you want non booleans… maybe some json. Oo wouldn’t it be nice if the json could conform to a schema… and then eventually you are like damn I really want to change these without deploying. Or you want to read the same flag from multiple services.
I’ve tried to incorporate this lowest common denominator into https://quonfig.com Use it totally free & open source as SDK, and it’s just loading JSON that you can track in git. Agents love it, hot reloads, SDK in lots of languages. But vs rolling your own you’ve got a lot of headroom on the design. A bunch of targeting operators. Segments etc. And then if you do want to get a nice UI / delivery network for real time updates, then you can use the paid side of things.
Local use description: https://docs.quonfig.com/docs/how-tos/open-source-local
> Yes to start out it’s 95% booleans. But then you want a rollout. And then you want some targeting rules. And then you want non booleans… maybe some json. Oo wouldn’t it be nice if the json could conform to a schema… and then eventually you are like damn I really want to change these without deploying. Or you want to read the same flag from multiple services.
First one got acquired. But also I wish I'd built it differently from the start (git based, other lessons learned), so started over.
It's true that it's a pretty simple thing, but you do want them to be of the utmost level of reliability. Its ideal if you can use feature flags & dynamic config (which I think of as the same problem) right at boot time. But then of course you have an external dependency to booting you app. So the reliability angle becomes imperative. So I do think the SaaS can play a good (or bad) role in overall reliability vs something you implement in house.
The other major advantage is telemetry. Once you have things toggling on and off, immediately engineers will get confused about whether something is on or off and why. Basic internal apps usually don't have any good telemetry / debugging. So a good SaaS should give you all kinds of ways to ensure that you can see what context is being passed around to the SDK to do their eval. Sanity checking etc.
My og experience was at HubSpot where we used the hell out of dynamic config. Once you get used to things like instantly targeting debug log levels for a single class to a single org its hard to go back.
There can be whole UIs and tooling and infrastructure to manage around them and that’s what the sass offer
something like enabledFeature = (flag1 || flag2 || flag3) && flag4
then, down the road, you remove flag4. Hopefully the above would result in a compile error but you may be in a language or situation where a missing flag4 is interpreted as boolean false. That could cause all kinds of havoc in logical combinations like that are scattered all over the codebase. Even worse would be REST APIs retrieving flag values because who knows what's happening in that service code? Plus, you'd never know there was an issue until users start reporting missing or extra features showing up unless you have e2e tests for every possible combination of feature flags...
You need to find every occurrence of flag4 and remove references to it. So that boolean expression would need to have `&& flag4` removed.
Immediately create story to remove said feature flag controlling access to the feature and review it during backlog refinements.
In my experience, engineers aren't using them to account for managerial dithering, they're doing it for safe deployments and experiments and rollouts and such. A product with millions of users can easily have a tens or even hundreds of active switches at any moment (I'm assuming a large engineering team behind said product), and that's not necessarily a bad thing.
However, as someone else noted here, you absolutely MUST delete and clean up your flags/gates/whatever when you've completed that effort. That part can be tricky because not everyone has the discipline to pay off tech debt.
Usually, a flag/gate should not live in code for more than a few months. If it does, it should have robust justification.
1. For reducing outliving, I always create a ticket to remove the flag at the same time it gets added in. This way there's documented work that will get scheduled. YMMV depending on how your team does planning.
2. For flag branch implementations, it's often fine to do an if/else, but I've seen this blow up into a real headache. When I can, I like having two implementations of an interface that get swapped between. Code calls the interface as normal the the underlying implementation is the same. Works for React components and larger implementations/changes that already have an interface. Don't want to force an interface where it feels wrong.
Specifically, the idea of putting toggles on risky functionality is a good idea that is useful broadly. Being able to dynamically toggle feature flags without a restart, or apply some features to some segment of users is unlikely to be useful and entails a lot of complexity and potential footguns.
My approach to feature flags is even simpler than what is suggested here: feature flags are just a section in your config. Done. Even if you are confident that you need more advanced capabilities, you should not "advance" to that level until you have demonstrable proof that your team can manage simple config values for it.
I can't hard code any of the flags until I have big customers notified and onboarded with the change.
So one would say why aren't your customers onboarded with the change before you implement it. Well no because they have 20-30 other applications they are using on daily basis.
While yeah we can push some customers to new features, we still need to have some realistic adoption in place before we can switch ... mostly because we are not Attlasian or Microsoft — we have actual people taking angry calls and angry e-mails from the customers.
There are no solutions, only tradeoffs.
I'll give some examples:
Firm 1 had a single server running tron [0] for ALL scheduling of processes.
Pros: very easy to see what should run when and made audits a breeze
Cons: the central server died and it was a giant outage response to make sure that when the server came up it didn't start killing processes that should be running
Firm 2 used a management gui to create custom cron entries on each machine
Pros: each node had a local copy of the schedule and could keep going even if the central system died
Cons: each node had a local copy of the schedule which could "drift" from other nodes, a node could be forgotten etc
So, more generally, I agree that it's good to label things as "ok" so that we don't get into flame wars etc. That being said, the more important point is to say that if you are going to pick a strategy, do the work to support, build tooling and plan for outages related to that strategy.
When something does go wrong, the compiler degrades gracefully, and still can make sense of most of the code.
MS gets a lot of flak (sometimes deservedly so), but they can sometimes also show what a large organization of skilled individuals working under consistent direction is capable of.
Any configuration read out of a JSON file is not hardcoded. Hardcoded means you need to recompile to change it.
(And yes, hardcoded, as in flags set with #define or equivalent, are totally fine depending on what you're doing.)
When your architecture grows and you start needing to synchronize configuration across multiple applications, or have non-technical users change flags, then you've probably outgrown hardcoding and need to consider building (or buying) a service. You probably don't want product owners trying to set an env var like `FeatureManagement__NewFeature__EnabledFor__0__Name`. Azure App Configuration is the go to if you're willing to use Azure - it provides a nice UI for editing flags instead of dealing with JSON. Or, I've been building https://featureflags.app/ as an alternative provider if you prefer to steer clear of Azure. Its kinda the middle ground between hard coding and a full on platform like LaunchDarkly.
Simple, effective, cheap, easy to understand and manage. Not dependent on an external service, not dependent on a third-party.
That covers a lot of uses of feature flags without the bloat.