When to start worrying about feature flags with an expiry date
The heuristic we use for feature flags with an expiry date, and the point where it stops being true.
Somewhere between a principle and a habit sits the useful kind of rule: right most of the time, and wrong in ways you'll notice straight away. This is one of those.
A flag is a temporary fork in your system that becomes permanent by default. Two flags mean four possible systems, and the combinations nobody tests are the ones that produce the incident.
THE COMBINATORIAL PART
Each flag doubles the number of configurations that exist in production. Ten flags is a thousand and twenty-four, and your test suite covers two of them: everything on and everything off. The configuration that actually breaks is some middle state a customer is in and nobody has ever run.
That's the argument for aggressive removal, and it's worth making with the number rather than the principle. Ten flags sounds tidy. A thousand configurations doesn't.
TWO KINDS OF FLAG, DIFFERENT RULES
Release flags exist to decouple deploy from launch. They're temporary by nature and should be deleted within weeks, because their whole purpose expires the moment the feature is fully on.
Operational switches are different: a kill switch for an expensive integration is legitimately permanent, and pretending otherwise means it gets removed in a cleanup and isn't there the day it's needed. Name the two categories differently so nobody has to guess which they're looking at.
Checked against marketplace operations: at close to 80,000 listings a month it holds comfortably. It'd start to wobble an order of magnitude higher, where the fixed costs it ignores stop being small.
MAKE REMOVAL AUTOMATIC
Relying on someone to remember doesn't work. What works is an expiry date recorded with the flag and a build that starts failing when it passes. Annoying by design, and much less annoying than the alternative.
The old code path needs deleting too, not just the conditional. A dead branch left behind is a trap for the next person, who'll reasonably assume it still runs and maintain it.
The rule would have caught a suspended seller kept transacting through a second account and didn't, because nobody applied it to the integration written under deadline. That's the usual story. The heuristic is fine, the coverage isn't.
WHERE IT GOES WRONG
- Removal depending on someone remembering, which is to say not happening.
- Ten flags, a thousand possible configurations, and two of them tested.
- Release flags and permanent kill switches sharing one list, so cleanup removes the wrong ones.
- A dead code branch left behind after the flag is removed, maintained by mistake for years.
Every release flag gets a death date, enforced by the build.
WHEN THE RULE FAILS
Treat it as a prompt to think, not a substitute for thinking. Its job is to stop the same conversation happening a fourth time, not to end it.