DEV Community

AvlCodeMonkey for AvlCodeMonkey Industries

Posted on Originally published at featureflags.app

Cleaning Up Feature Flags: The Art of Not Leaving a Mess

You said you'd remove that flag after launch. You lied. It's been six months and the flag is still in appsettings.json, the if statement is still in your controller, and nobody remembers which state is "on." This is how codebases turn into haunted houses.

Why Cleanup Matters

Dead feature flags are technical debt with teeth. They add branches to your code that nobody tests. They confuse new developers who don't know the history. They inflate configuration files and make deployments harder to reason about. And they compound.

Every flag you don't clean up makes the next cleanup harder because the cognitive load of understanding the system keeps increasing. The cost of removing a flag is lowest immediately after the feature ships, while everyone still remembers what the thing does. Six months later? Good luck.

Track Every Flag

You can't clean up what you can't find. Maintain a registry of every active feature flag with:

  • Name
  • Purpose
  • Owner
  • Date created
  • Expected removal date

This can be a spreadsheet, an issue tracker, internal documentation, or a dedicated feature flag management system. The format doesn't matter nearly as much as the habit. When you add a flag, add it to the registry. When you remove a flag, remove it from the registry. If your registry contains flags with no owner or no removal date, congratulations: you've found your next cleanup project.

Set Expiry Dates

Every flag should have a planned removal date when it's created. For example:

  • Release toggles: Remove shortly after the feature ships. Two weeks is a reasonable default.
  • Experiment toggles: Remove when the experiment concludes.
  • Ops toggles: May be permanent by design.
  • Permission toggles: May also be permanent, but document that explicitly.

If a flag has been alive longer than its planned expiry and nobody deliberately extended it, it's already a zombie. Treat it accordingly.

Make Cleanup Part of the Process

Flag cleanup doesn't happen unless someone owns it. Add a cleanup step to your feature completion checklist. Better yet, create the cleanup ticket when you create the feature ticket. The feature isn't done when it's released. It's done when the flag is gone.

Some teams set automated alerts when flags exceed their planned lifetime. Others track flag counts on engineering dashboards. The specific mechanism doesn't matter much. Having a mechanism does.

How to Actually Remove a Flag

Removing a flag isn't just deleting an if statement. Here's the full checklist:

  1. Determine which state the flag should permanently be in. Usually enabled if the feature shipped successfully.
  2. Remove the flag check and keep the code from the permanent path.
  3. Delete the disabled code path completely. Don't comment it out.
  4. Remove the flag definition from configuration and your flag management system.
  5. Update or remove tests that specifically covered the disabled state.
  6. Delete the flag from your registry.
  7. Deploy and verify.

Step 3 is where people get lazy. Commented-out code isn't deleted code. It's just code waiting to confuse someone six months from now. Delete it.

The Goal

A well-maintained codebase has only the feature flags it actually needs. Each flag should be:

  • Documented
  • Owned
  • Understandable
  • Actively used
  • Scheduled for removal

Clean up isn't a one-time event. It's an ongoing engineering practice. Feature flags should make your system easier to operate, not turn it into an archaeological dig.

If you want to make it easy to clean up your feature flags without editing configuration files in production, check out FeatureFlags.app.

The only good zombie flag is a deleted one.

Top comments (0)