Picture a flag called release_checkout_v3. It went from 0% to 100% over two weeks in March, nobody complained, and the team moved on to the next thing. In October it is still in the code, still evaluated on every checkout request, and the only person who remembers why it exists left in July.
The ramp was watched and the targeting was right. All of the management stopped at 100%.
Feature flag lifecycle management is the practice of running a flag all the way to the end. You decide how a flag will end on the day you create it. Later, when someone calls it “done”, you need to know which kind of done they mean. Code removal, archiving and deletion happen at different times and fail in different ways.
Key Takeaways
- Lifecycle management happens at the two ends of a flag’s life, creation and removal.
- Decide at creation whether a flag is temporary or permanent. Temporary flags get an owner and an end date. Permanent ones get a review instead.
- Removing the code, archiving the flag and deleting it are three operations with three different undo costs. Do them in that order.
- Archiving a flag that deployed code still reads makes every read fall back to its coded default, which for a rolled-out flag usually means off.
- An audit is a short list of filters you run on a schedule: unowned, past expiry, stale or dead, permanent and unreviewed, archived and quiet.
1. Six stages, and the one nobody owns
A temporary flag goes through six stages. It gets created, then released (the ramp from internal users to a percentage to everyone), and then it settles: one variation is served to everybody, or the flag is switched off and left off. After that come three exits. First the code that reads it comes out and ships, then you archive the flag in the platform, and some weeks later you delete it.
Someone created the flag on purpose, and someone watches the dashboard while it ramps, so the first two stages look after themselves.
A settled flag has finished its job, and no step in a normal sprint picks it up, because the feature shipped and the ticket closed weeks ago. Pete Hodgson’s description of toggles as “inventory which comes with a carrying cost” fits this stage, because a settled flag still costs you a conditional branch every engineer reads around and every test suite either covers or quietly ignores, and it does nothing in return. You can price that carrying cost for your own backlog in a couple of minutes.
Permanent flags have a shorter life. A kill switch for a payment provider or a flag gating a paid plan gets created and then kept, sometimes for years. Its lifecycle ends in a review instead of an exit.
2. Decide how the flag ends on the day you create it
Plan a flag’s removal when you create it. The person creating it knows what it is for and what “finished” will look like, and a year later nobody will.
So the first question at creation is whether the flag is temporary or permanent. Hodgson’s four categories map onto that split cleanly. Release toggles and experiment toggles are temporary by design. Ops toggles and permission toggles mostly stay. A naming convention that puts the type in the key (release_, experiment_, ops_, perm_) makes the answer visible to anyone grepping the code later, which is the person you are writing it for.
A temporary flag needs an owner, meaning one person accountable for taking it out. A team name doesn’t count, because a team can’t get an email and won’t feel guilty about a flag it never chose to own.
It also needs an end date. That’s a guess, and nobody will hold you to it. A release flag ramping over two weeks might get a date six weeks out. When the date passes, its owner removes the flag or moves the date and writes down why. Setting a default lifetime for a whole project covers the flags people forget to date. The pull request that introduces the flag is the natural place to ask for an owner and a date, and it’s the first section of our feature flag code review checklist.
A permanent flag gets the opposite treatment. It should be marked as permanent so that the tools looking for finished flags stop reporting it. A kill switch serving true to everyone for a year looks exactly like a finished rollout to anything reading traffic. Without the marker, it keeps showing up in cleanup queues until somebody removes it by mistake.
3. Remove, archive, delete: three different operations
“Clean up the flag” can mean three things. Treat them as one and the archive lands before the deploy.
| Operation | What it changes | How you undo it | When to do it |
|---|---|---|---|
| Remove the code | The flag check disappears from your source, and the losing branch goes with it | Revert the commit and redeploy | Once the flag has settled |
| Archive the flag | The flag leaves the evaluation payload, and every SDK still reading it falls back to its coded default | Restore it, and its configuration comes back intact | After the code removal is deployed everywhere that reads the flag |
| Delete the flag | The flag and its configuration are gone from the platform | Recreate it by hand | After it has been archived and quiet for a while |
Removing the code is the part with real engineering in it, and the cleanup playbook covers it in depth, including the two-PR pattern that makes the path unconditional first and deletes the dead branch second. The two platform operations get less attention because they look like housekeeping, and archiving is the one that can take a feature down.
4. Code first, then archive, then delete
On Featureflip, an archived flag leaves the evaluation payload within seconds of the archive, connected SDKs drop it, and every read of it returns the default value written beside the call at that call site.
For a flag that rolled out to 100%, production has been serving the on variation for weeks. The default sitting next to the read is the value its author wrote for the case where the flag can’t be reached at all, and that is off at most call sites, because off is the safe guess when you write the line. So archiving a rolled-out flag while a build that reads it is still running turns the feature off. For everyone. Until the build that no longer reads it is deployed.
Merging the removal is the moment it feels finished, which is why archiving at merge time is so tempting. In a pipeline where production deploys are a manual promotion, the merge and the deploy can be days apart, and on a Friday afternoon, longer.
Featureflip refuses to archive a flag while it can still see that flag being evaluated, and the refusal names the environments still reading it. The dashboard, the MCP server and the cleanup Action all hit that check, and the Management API skips it only when a caller passes force explicitly. The refusal clears by itself once the new build is out and the old traffic drains. The check reads telemetry, though, so it can only rule on what it has seen. Code that is deployed but rarely reached (a monthly billing job, an admin page nobody opened this week) can look drained when it isn’t. Before archiving, confirm the deploy, and don’t take silence as proof.
Clients you can’t update are the hard case. A mobile app version from eight months ago keeps evaluating the flag for as long as people keep running it, so the refusal never clears. For those flags, archiving is a call you make once the old versions have aged out, and force is there for exactly that.
Delete comes last and slowly. An archived flag keeps its configuration and history, so a surprise two weeks later costs one restore. Delete it, and someone rebuilds the rules from memory. Featureflip also won’t delete a flag that another flag still lists as a prerequisite, or archive one that a live flag depends on, so dependency chains come apart from the leaves inward.
5. How to tell a flag is ready to come out
Ask a team of ten which flags are finished and you’ll get the ones they happen to remember. Evaluation traffic lists every flag that has stopped making a decision, including those whose creators have left.
Stale flag detection checks each flag in each environment for four signals. Fully rolled out means one variation served to at least 99.9% of evaluations. Rolled back means switched off with at most one variation served. No traffic means enabled but no longer evaluated. Never used means created and never evaluated in that environment. A signal held for 30 days marks the flag Stale. Held for 90, it is Dead.
A fully rolled-out flag is simply done, so make the winning path unconditional and remove it. A rolled-back one means someone switched the feature off and walked away, and you should find out whether it is coming back before deleting the code for it. No traffic usually means the reference went in some refactor and the flag got left behind, so check and then go straight to archiving. Never used is the quickest of the four to clear, since nothing ever read it.
A passed end date is a fifth reason, and a different kind. It means the owner’s own deadline has arrived. Whether the flag still matters is a separate question, so the date opens a conversation with the owner, and the traffic signals decide the removal. Environments disagree, too. A flag can be Dead in production while a forgotten staging config still serves both variations, and the flag isn’t finished until every environment agrees.
6. Auditing the flags you already have
Adopting lifecycle rules doesn’t touch the 200 flags already in the list. An audit pulls that backlog in and keeps it in. We’d run it monthly for a team creating five or so flags a week, and the whole thing is a handful of filters on the flag list.
Unowned flags come first. Each one gets an owner or gets removed, and the audit log shows who last changed it, which makes that person the first one to ask. When someone leaves, reassign their flags in the same step, or they drift into nobody’s queue.
Owners of expired flags remove them or move the date, with a sentence on why. If a date has moved three times, mark the flag permanent and review it as one.
Work through Stale and Dead by reason, as in section 5, with the Dead ones first.
Permanent flags need a different question. Is this kill switch still wired to anything, and has anyone flipped it since it was created? An ops toggle nobody has flipped might not work on the night you need it. The anti-patterns post has outage stories from exactly that. A permanent flag nobody can explain should lose its marker and go through the temporary path.
In the archived list, anything archived and quiet for a few weeks can be deleted, unless it is waiting on old mobile versions to age out.
On a project with a few hundred flags the first pass can take an afternoon, since it inherits years of backlog. The monthly ones after it are short, because each only has to catch a month of new flags.
7. Where Featureflip fits
Most of this is process, and it works on any flag platform that exposes owners, dates and evaluation data. Featureflip builds the lifecycle into the flag itself.
Expiry dates, a default lifetime per project, and the permanent marker are on every plan, Free included. Flag owners are on Pro and above, with a reassignment step when someone leaves the organization. Cleanup notices arrive on Team and above as a daily digest when a flag passes its date or goes Dead in every environment, sent to the flag’s owner where it has one and to your admins otherwise. Stale detection runs hourly on every plan with no setup, since it reads the evaluation traffic the platform already has.
For the code half, the flag cleanup Action opens a pull request removing a dead flag’s code, and a second scheduled workflow archives the flag after the removal merges. It defers while the flag is still being evaluated, so the order from section 4 holds even when a person isn’t watching. The automated removal post explains what that kind of tool has to refuse to be safe, and the flag lifecycle overview puts the product pieces side by side.
Paid plans include unlimited flags at a flat price, and that shapes lifecycle habits. Under a per-flag meter, the cheap move for a new feature is to repurpose a finished flag, and that piles flag debt onto a key whose history nobody remembers.
The shorter version
- A flag’s lifecycle is managed at creation and at removal.
- At creation, decide temporary or permanent. Temporary flags get an owner and an end date, and permanent ones get the marker and a periodic review.
- Removing code, archiving and deleting are three operations. Do them in that order.
- Archive only after the code removal is deployed everywhere that reads the flag. An archived flag sends every remaining read to its coded default.
- Use evaluation traffic to find finished flags, and act on the reason as well as the badge.
- Audit monthly with filters: unowned, expired, Stale or Dead, permanent, archived.
Frequently asked questions
What is feature flag lifecycle management?
It is the practice of running each feature flag from creation to removal on purpose, instead of letting it stay in the code after its job is done. In practice it means classifying every flag as temporary or permanent at creation, giving temporary flags an owner and an end date, finding finished flags from evaluation data, and then removing the code, archiving the flag and finally deleting it, in that order. Permanent flags such as kill switches get a periodic review instead of a removal.
When should you archive a feature flag?
After the code that reads it has been removed and that change is deployed to every environment and client that evaluates the flag. Archiving removes the flag from the evaluation payload, so any build still reading it falls back to the default written in the code, and for a fully rolled-out flag that default is usually off. Featureflip refuses to archive a flag it can still see being evaluated, but you should confirm the deploy yourself, especially for rarely-run code and mobile apps.
What is the difference between archiving and deleting a feature flag?
Archiving takes the flag out of evaluation but keeps its configuration and history, so you can restore it if something still needs it. Deleting removes it from the platform permanently. Archive first, wait until the flag has been quiet for a while, and delete after that. Featureflip blocks deleting a flag that another flag still lists as a prerequisite.
How long should a feature flag live?
As long as its type needs. A release flag should live through the rollout and a short settling period, two to six weeks in all, and then come out. An experiment flag lives until the experiment has a result. Kill switches, ops toggles and flags that gate paid plans can live for years, and those should be marked permanent so they stop appearing in cleanup reports.
Should a permanent feature flag have an expiry date?
No. An expiry date says you plan to remove the flag, and a permanent marker says you don’t, so the two contradict each other. Featureflip refuses the combination and asks you to pick one. Review permanent flags on a schedule instead: check the kill switch is still wired up, that it has been tested, and that someone can still explain why it exists.
Featureflip is a flat-priced feature flag platform with expiry dates, flag owners, stale flag detection from real evaluation traffic, and a GitHub Action that opens the pull request removing a dead flag’s code. Paid plans include unlimited flags, so creating a fresh flag for new work never costs more than reusing an old one. Start on the Free plan without a credit card.