Cleaning Up Feature Flags Before They Clean Up You
Feature flags stay useful only when every flag has an owner and a removal date, and stale ones get deleted. A flag meant to live two weeks often lingers for a year, and every engineer touching that code path must reason about both the on and off states even though only one has mattered for months.
This is a practical checklist for keeping that from happening, and for cleaning up the flags that already have.
Give Every Flag an Expiration Date at Creation
Set an expected removal date the moment a flag is created, not as an afterthought once someone notices it's stale. A permanent flag, one genuinely meant to live indefinitely for something like a kill switch, should be explicitly marked as such, so it's excluded from cleanup sweeps instead of showing up as clutter every time someone reviews the list.
This single habit does more to prevent flag debt than any cleanup process applied after the fact, because it turns removal into a planned step instead of a discovery.
How do you find flags stuck fully on or fully off?
A flag that's been fully rolled out to everyone, or fully rolled back to no one, for months is no longer actually a flag, it's dead code wearing a flag's clothing. Pull a report of every flag's current rollout percentage and how long it's been stable at that percentage, and treat anything unchanged for an extended period as a cleanup candidate.
This audit is usually the fastest way to find the bulk of your flag debt, because most stale flags aren't ambiguous once you look, they're just sitting fully on or fully off and nobody's gotten around to deleting the code.
Some flags legitimately need to stay partially rolled out for a while, a gradual regional expansion or a slow migration, so check the trend, not just the current number, before flagging something as stale. A percentage that's been climbing steadily is different from one that's been frozen for months.
How do you remove a feature flag safely?
Confirm the flag's current state in production matches what you're about to hardcode before deleting anything, since removing a flag is effectively a deploy of whatever state you assume it's in. Delete both the flag definition and every conditional branch tied to it, not just the flag configuration, or you'll leave dead, unreachable code behind that looks like it's still doing something.
Remove flags in small batches with normal code review, the same as any other change, rather than as a big end-of-quarter cleanup sprint that tries to touch everything at once.
Flags and Your Deploy Frequency
Feature flags exist partly to decouple deploying code from releasing behavior, which is a big part of what lets a team safely increase its deploy frequency. But that benefit erodes as stale flags pile up: each one adds a conditional branch every future change has to reason around, which drags directly on the same deploy frequency the flags were meant to help improve1.
Treat flag count as a health metric worth watching, not just a list to clean up eventually. A steadily growing count of long-lived flags is a sign the cleanup habit isn't keeping pace with flag creation, and that gap tends to widen on its own once it starts, since more flags make every future cleanup pass slower and more error-prone.
Assign Ownership Before It Becomes Nobody's Job
A flag with no clear owner tends to outlive the reason it was created, because nobody feels responsible for closing the loop once the rollout is done. Assign an owner at creation, the same engineer or team who added the flag, and make flag cleanup part of what closes out the related project, not a separate task competing for attention later.
A short recurring review, even fifteen minutes on a regular cadence to check the stale-flag report, keeps this from becoming a large, dreaded cleanup project down the line.
A short flag hygiene checklist:
- Set an expected removal date when each flag is created, and mark genuinely permanent flags, such as kill switches, so cleanup sweeps skip them.
- Assign an owner at creation, the engineer or team who added the flag, and make cleanup part of closing out the related project.
- Pull a report of rollout percentages and treat any flag unchanged for an extended period as a cleanup candidate.
- Before deleting, confirm production state matches what you will hardcode, then remove the flag definition and every conditional branch tied to it.
What Good Looks Like
Good feature flag hygiene means every flag has a named owner and an expected removal date set at creation, with a regular review that catches flags sitting fully on or fully off for too long before they turn into permanent clutter.
Building The Capability (5-Stage Skill Ladder)
How to Get Started
Frequently Asked Questions
How do we know which feature flags are safe to remove?
Start with flags that have been fully rolled out or fully rolled back for an extended period without changing. Those are effectively dead code wearing a flag's clothing. Confirm the current production state before removing the flag, and delete both the flag definition and every code branch tied to it, not just the configuration.
Should every feature flag have an expiration date?
Every temporary flag should, set at the moment it's created rather than decided later. A genuinely permanent flag, like a kill switch, should be explicitly marked as permanent so it's excluded from cleanup sweeps instead of cluttering the stale-flag list every time someone reviews it.
Do stale feature flags actually slow down our releases?
Yes, in a real way. Each stale flag adds a conditional branch that every future change through that code has to reason around, which works against the same deploy speed and safety flags were originally meant to provide. A growing count of long-lived flags is worth treating as a warning sign, not just clutter.
Who should be responsible for cleaning up old feature flags?
Whoever created the flag, as part of closing out the project it was built for, rather than leaving cleanup as an unowned task that competes with everything else later. A short, recurring review of the stale-flag report keeps this manageable instead of turning into a large, dreaded cleanup effort.
Sources
Where we quote a benchmark, we show its source. Other figures in this guide are estimates or general guidance, so check them against your own numbers.
- Deployment frequency by DORA performance cluster (max days between deploys). DORA Accelerate State of DevOps 2024 (Google Cloud), cluster table via Octopus Deploy analysis, 2024.
Related Guides
A Checklist for Cleaning Up Feature Flags Before They Become Their Own Codebase
A checklist for finding and safely removing stale feature flags, and the pitfalls that turn a routine cleanup into a production incident.
The Feature Flag Cleanup Habit Most Teams Never Build
Why feature flags pile up unused for years, and a simple habit that keeps your flag count from becoming its own source of bugs.
The Feature Flag Graveyard Nobody's Cleaning Up
Feature flags accumulate faster than anyone notices, and the old ones left behind carry a real cost. A checklist for finding and safely deleting them.
Verifying Devices Before They Touch Production, Not After
How to build device verification into a zero-trust rollout, what actually counts as a trust signal, and where teams stop checking too early.
A Production Deployment Checklist That Actually Catches Problems
A stage-by-stage deployment checklist for distributed systems, covering rollback readiness, dependency ordering, and the checks teams skip under pressure.
A Checklist for Cleaning Up Feature Flags Before They Rot
The common ways feature flags turn into permanent technical debt, and a checklist for cleaning them up before they become a security risk.