The feature flag that outlived the feature
Flags are supposed to be temporary. The ones that stick around become permanent forks in your code — untested branches, dead config, and a boolean nobody remembers the meaning of.
Hammad Iqbal
Software Engineer
A feature flag is a promise to yourself that you'll come back and delete it. You add it to ship safely, roll the feature out to 100%, move on to the next thing, and the flag stays — now a permanent `if` with one branch that's run in production for months and one that hasn't been executed or tested since the rollout finished. Multiply that by every feature the team has shipped this year.
- Every live flag doubles the number of code paths, and only one side stays tested.
- A flag with no owner and no removal date is config debt that compounds silently.
- Deleting the flag is part of shipping the feature, not a separate cleanup task for later.
A flag is a branch you stopped testing
Once a feature is at 100%, the `false` branch of its flag is dead code that's still compiled, still shipped, and still capable of being re-activated by a stale config value or a bad merge. Your tests almost certainly only cover the path that's live. The other one rots — and the day someone flips it back on to debug something, they're running code that hasn't seen a real request in six months.
Flags need an owner and an expiry
The flags that linger are the ones that belong to nobody. A flag added in a hurry, by someone who's since moved teams, with a name like `new_flow_v2` that no longer maps to anything anyone remembers. Give every flag a recorded owner and an intended removal date when you create it, and make stale flags visible:
- Record the owner and a target removal date in the flag's description or a tracked list
- Run a periodic check that lists flags older than 60 days and pings their owner
- Distinguish short-lived release flags from long-lived operational kill switches — only the first kind should expire
- Treat a flag stuck at 100% for a month as a bug ticket, not a nice-to-have
Removal is part of the feature
The cleanest way to stop accumulating flag debt is to not consider a feature done until its flag is gone. Ship behind the flag, roll out, watch it, then open the PR that deletes the flag and collapses the branch — while you still remember which side won and why. Left for 'later', that PR competes with every new feature and loses every time.
A feature flag you haven't touched in two months is either a kill switch you should document as one, or debt you should delete this week. It's very rarely nothing.
Have a project this kind of thinking applies to?
Tell me what you're building — I read every message myself.