Flag Cleanup & Technical Debt in Flagsmith

Flag Cleanup & Technical Debt in Flagsmith

A plain-English guide to the quiet problem that grows behind every successful feature flag programme: old switches nobody remembers. Learn why flags turn into debt, how to spot the stale ones, and how to retire them safely and routinely.

Imagine opening a drawer in your kitchen and finding forty keys. Some open doors you no longer own. Some open nothing at all. A few open something important, but nobody can say which. Every time you leave the house you pick up a handful, hoping you chose well. Now imagine that drawer is part of a system serving millions of customers.

That drawer is what a feature flag setup becomes when nobody cleans it. Feature flags are wonderful when they are young. They let you release gently, test safely and switch off trouble in seconds. But every flag you create is also a promise to remember it later, and promises that nobody tracks are broken quietly. After a year, the flag list is long, the code is full of branches nobody dares to touch, and a simple change takes twice as long because no one is sure what each switch does.

You do not need to know anything about software maintenance or feature flags to follow this guide. Every new word is explained when it first appears, with an everyday comparison. By the end you will understand what flag debt is, how to measure it, how to prevent most of it, and how to retire old flags in Flagsmith safely, step by step, without frightening anyone.

1Starting From Zero: Flags and Why They Pile Up

First, a short reminder of what a flag is, and why it is so easy to create and so easy to forget.

Feature flags in one minute

A feature flag is a switch in your software that decides whether a feature is visible. Instead of hiding a new button by deleting code, you wrap the button in a check: “if the flag is on, show it.” Later you flip the flag in a dashboard and the button appears or disappears without shipping a new release. A remote config value is a close cousin. Instead of just on or off, it holds a number or some text, such as how many items to show per page.

Why creating a flag is cheap

Making a flag takes seconds. You type a name, click create, and add a check to your code. There is no meeting, no ticket and no review needed to feel safe. That ease is exactly why flags are loved. It is also the reason they multiply. Anything that is cheap to create and free to keep will be created often and kept forever, unless somebody decides otherwise.

Why removing a flag is expensive

Removing a flag is different. Someone must confirm that no code still reads it, that no customer still depends on the old behaviour, and that the flag is not secretly guarding something important. They must change code, test it, release it and then delete the flag. None of this is exciting, and none of it ships anything new. When teams are busy, cleanup slides down the list again and again.

Analogy

Think of the sticky notes on a shared office fridge. Putting one up takes two seconds. Taking one down requires knowing whether it is still needed, whose it is, and whether somebody will be upset. So nobody takes them down, and eventually the fridge door is buried under yellow squares. Flags are sticky notes for your code.

The asymmetry that creates debt

Cheap to create, costly to remove, and rarely owned: that three-part combination is the root of almost every flag cleanup problem. The rest of this guide is about changing that balance, by making creation slightly more careful, and removal much easier.

!
Tip

Whenever you meet a new word in this guide, ask three questions: what is it, why does it exist, and what would break without it? Those answers explain most of what you need to know.

2What Technical Debt Means

A borrowed idea from money, applied to code.

The original idea

The phrase technical debt was popularised by a software engineer named Ward Cunningham. The idea is simple. When you take a shortcut in your code to ship sooner, you are borrowing time from your future self. The shortcut works today, but you will have to pay it back later, and until you do, you pay interest: everything related to that code takes a little longer, breaks a little more easily and confuses a little more people.

Not all debt is bad

Borrowing is not wrong in itself. A company that borrows to open a shop may earn far more than the interest costs. In the same way, a quick, temporary flag that lets you launch a feature this week may be exactly the right decision. The trouble begins when the debt is forgotten, when nobody knows how much exists, and when the interest quietly grows larger than the benefit ever was.

Debt versus mess

It helps to separate honest debt from plain mess. Honest debt is a deliberate choice with a plan to repay: “we added this flag to launch safely, and we will remove it by the end of next month.” Mess is the same flag with no owner, no date and no memory. The first can be managed. The second can only be discovered later, usually at a bad moment.

Principal

The work to remove it

The effort needed to delete the flag and its old code. It stays roughly the same size, or grows slowly, as long as you wait.

Interest

The ongoing slowdown

Extra reading, extra testing, extra explaining and extra risk, paid every single week the flag stays.

Default risk

The chance of a nasty surprise

The probability that an old flag is flipped, deleted or misunderstood at the worst possible time.

Repayment

Cleanup done on schedule

Removing flags soon after they have done their job, when the memory of why they exist is still fresh.

Analogy

A small leak under a sink costs almost nothing to fix on the day it starts. Left alone, it rots the cupboard, then the floor, then the ceiling below. The leak itself never changed. The cost of ignoring it did. Flag debt behaves the same way.

!
Watch out

Debt that nobody can see is the most dangerous kind. The first goal of this guide is not to delete anything. It is to make your flag debt visible and measurable.

3Not Every Flag Is the Same: The Four Kinds

The right cleanup plan depends entirely on what the flag was meant to do.

Teams that treat all flags alike either delete useful switches by mistake or keep useless ones forever. A better habit is to sort flags into kinds, because each kind has a different natural lifespan. A widely used way to sort them has four groups.

KindPurposeNatural lifespanCleanup rule
Release flagShip code safely, then roll out graduallyDays to weeksRemove soon after full rollout
Experiment flagCompare versions to learn which works betterWeeks, until a winner is chosenRemove after the decision, keeping the winner
Operational flag, or kill switchTurn off risky behaviour quickly during troubleLong-lived, sometimes permanentReview regularly, never remove casually
Permission or entitlement flagDecide who gets which paid or special featuresLong-lived, tied to the productTreat as product configuration, not debt

Release flags: the usual suspects

Most flag debt comes from release flags. They are created with a clear, short job: hide an unfinished feature until it is ready. Once the feature is fully released to everyone, the flag is dead weight, yet it remains because nobody circles back. If you remember one rule from this guide, make it this one: a release flag is born with an expiry date.

Experiment flags

An experiment compares two or more versions of something, such as two checkout designs, to learn which performs better. When the experiment ends, someone must pick the winner, make it the only version and remove the losing code and the flag. Experiments that end without a decision leave behind a flag that still splits users forever, quietly confusing later analysis.

Operational flags

A kill switch is a flag kept on hand to turn off a risky or expensive behaviour instantly, for example a feature that depends on a slow outside service. These are meant to live a long time. They are not debt in the same sense, but they still need owners and regular checks, because a kill switch nobody has tested may fail on the day it is needed.

Permission flags

Flags that decide who has access to which paid features are really product configuration wearing a flag’s clothes. They do not belong in a clean-up drive. They belong in a clearly labelled group so that nobody mistakes them for forgotten experiments.

Analogy

A building has scaffolding, fire exits, door locks and signs. Scaffolding is removed when the repair ends. Fire exits stay forever. Mixing them up is dangerous in both directions: you do not want to leave scaffolding up for years, and you certainly do not want to take down the fire exits during a tidy-up.

!
Tip

Record the kind of every flag at the moment of creation, using a tag. Cleanup rules then become simple: temporary kinds expire, long-lived kinds are reviewed.

4The Real Costs of Leaving Flags Behind

Old flags are not harmless. They quietly tax every part of the work.

Cost one: code that is hard to read

Every flag check is a fork in the road. A reader of the code must hold both paths in mind: “if the flag is on, this happens; otherwise that happens.” With one flag, that is easy. With fifty nested flags in a single area, nobody can say what the program does without checking a dashboard, and even then the answer may differ by environment.

Cost two: a testing explosion

Each flag doubles the number of possible states of the program. Two flags give four combinations, three give eight, and ten give over a thousand. Nobody tests all of them. The untested combinations are where surprising bugs live, and they appear only for the unlucky customer whose settings happen to land on that combination.

2
flags give 4 possible combinations
10
flags give 1,024 possible combinations
20
flags give over a million combinations

Cost three: operational risk

A stale flag is a loaded switch with no label. Someone flips it by accident, a script changes it in bulk, or a new teammate guesses wrongly about what it does. A publicly reported trading incident from 2012 is often told as a warning: an old, long-forgotten switch was reused for a new purpose, and on one server the old code behind it was still alive. The result was a very costly failure within minutes. The details are well documented online, and the lesson is simple: dead code behind a live switch is a hazard.

Cost four: slower onboarding

New teammates must learn which flags matter and which are fossils. Without a record, they learn by asking, and the answers differ from person to person. Each confusion costs hours, and experienced engineers are interrupted again and again to explain history that should have been deleted.

Cost five: clutter in the tools

A dashboard with nine hundred flags is hard to search, slow to scan and easy to misread. Real, important flags are buried among dead ones. People stop trusting the list, and a list nobody trusts is a list nobody maintains.

Cost six: wasted effort and money

Dead flags still get evaluated, logged and carried through every release. Dead code still compiles, still gets scanned by security tools, and still needs updating when libraries change. Each of these costs is small. Together, and multiplied across years, they are significant.

Analogy

A garage full of old boxes slows down every search for the one tool you need. It makes the car hard to park and the floor hard to sweep. No single box is the problem. The accumulation is. Stale flags are boxes in the garage of your code.

!
Watch out

Do not wait for a disaster to justify cleanup. By then the debt is large, the knowledge is gone and the work is urgent. Small, regular, boring cleanup is far cheaper than heroic cleanup after an incident.

5The Life of a Flag: From Birth to Removal

Cleanup is easiest when it is planned as the last chapter of a flag’s story, not an afterthought.

flowchart LR
  A["Idea: ticket created"] --> B["Birth: flag created with owner, kind and expiry"]
  B --> C["Build: code added behind the flag"]
  C --> D["Rollout: staff, small group, everyone"]
  D --> E["Stable: flag on for all, no more changes"]
  E --> F["Retire: remove code, archive flag"]
  F --> G["Delete: flag removed from Flagsmith"]
Figure 1. The healthy life of a temporary flag, from idea to deletion.

Stage by stage

1

Idea

A ticket describes the feature. It includes a line that says “remove the flag” so that cleanup is part of the work from the first day.

2

Birth

The flag is created with a clear name, a description, an owner tag, a kind tag and a target removal date.

3

Build

Code is written behind the flag, with the old behaviour preserved as the safe path.

4

Rollout

The feature is shown to staff, then a small percentage, then everyone, with graphs watched at each step.

5

Stable

The flag is on for everyone and nothing is changing. This is the moment the clock for removal truly starts.

6

Retire

Developers delete the flag checks and the old code path, release the change, and watch for problems.

7

Delete

After a quiet period, the flag is archived and then deleted in Flagsmith, and the ticket is closed.

Where debt sneaks in

Almost all flag debt appears in the gap between stages five and six. The feature works, everyone is happy, attention moves to the next project, and the cleanup ticket sinks. A simple way to close the gap is to schedule the removal at the same moment the rollout reaches one hundred percent, while everyone still remembers why the flag exists.

Analogy

When you finish painting a room, you peel off the masking tape the same day. Left for a month, the tape bakes onto the wall and takes the paint with it. A flag left after a rollout is masking tape that is getting harder to remove every day.

6How Flagsmith Is Organised, and Where Debt Hides

To clean thoroughly, you must know every place a flag leaves a trace.

The containers

Flagsmith organises everything in layers. An organisation is your company account. A project is usually one product. An environment is one stage of that product, such as development, staging or production. A feature is the definition of a flag, shared across the whole project. A feature state is the value of that feature inside one environment.

The traces a flag leaves

Deleting a flag in the dashboard removes only one of its traces. A thorough cleanup considers all of them.

In code

Flag checks

The conditions that read the flag, plus the old branch of code that runs when the flag is off. This is usually the largest piece of debt.

In code

Default values

The fallback entries kept in your SDK setup. They linger quietly after the flag is gone.

In tests

Test scenarios

Tests that switch the flag on and off. They must be simplified when only one path remains.

In Flagsmith

Feature and feature states

The flag itself, with a separate value in every environment.

In Flagsmith

Segment overrides

Special values for groups of users, which keep influencing decisions until removed with the flag.

In Flagsmith

Identity overrides

Special values for individual users, easy to forget and surprising to rediscover.

Around

Integrations and webhooks

Dashboards, alerts and automations that mention the flag by name.

Around

Documents and tickets

Runbooks, wiki pages and tickets that tell people the flag exists.

Environments drift

A flag can be fully on in production, half on in staging and off in development. When it is time to remove it, each environment must be considered. If the flag still has different values in different places, you must decide which value represents the truth before deleting it, because the code you keep must match the behaviour you want everywhere.

!
Tip

Before removing a flag, list all its traces in a short checklist. A flag that has been fully removed from code but still has identity overrides in Flagsmith is half-cleaned and will confuse the next person to find it.

7Prevention: Starting Every Flag With the End in Mind

The cheapest cleanup is the cleanup you planned on the day the flag was created.

The birth certificate

Every new flag should be created with a small set of information, a sort of birth certificate. It takes one minute to fill in and saves hours later.

FieldExampleWhy it helps
Namecheckout_new_payment_formSays what area and what change, so graphs and logs explain themselves
DescriptionShows the redesigned payment form to eligible usersGives future readers the reason, not just the label
Owner tagteam-paymentsTells everyone whom to ask
Kind tagreleaseDecides whether the flag should expire
Removal dateWithin thirty days of full rolloutTurns a vague intention into a visible deadline
Ticket linkLink to the work itemConnects the flag to its story and its cleanup task

Naming that lasts

Good names are the cheapest form of documentation. Begin with the product area, describe the change and avoid names that depend on who asked for it or when it was made. Avoid vague words such as test, new and temp, which age badly. Use the same word separator everywhere so searches work. A name like checkout_new_payment_form will still make sense in two years. A name like newflag2 will not make sense in two weeks.

Tags as the glue

Flagsmith lets you attach tags to flags. Tags are the easiest way to record owner and kind, and they make filtering simple: “show me every release flag owned by the payments team.” If tags are applied consistently from the start, most of the reports and automations later in this guide become simple to build.

Make the removal task part of the plan

The most effective prevention habit is to create the removal task at the same moment as the flag. Put “remove flag and old code” into the original ticket as its own checklist item, or open a linked ticket with a due date. A task that exists from the beginning is far more likely to be done than a good intention.

Analogy

A responsible camper packs a rubbish bag with the tent. The bag is not an afterthought. It is part of the packing list, so leaving no trace is simply what happens. A removal task created with the flag is the rubbish bag in your pack.

!
Watch out

Do not rely on memory or goodwill. Teams change, priorities shift, and the person who created a flag may have left. Write the owner and the expiry where everyone can see them.

8Finding the Stale Flags: Detection

Before you can clean, you must know what is dirty.

What “stale” means

A stale flag is one that has stopped doing useful work. Its value no longer changes, or its decision no longer matters, but it still sits in the code and the dashboard. Staleness has several faces, and good detection looks for each.

Signal

Old and unchanged

The flag was created long ago and has not been edited for months. Temporary flags in this state are prime suspects.

Signal

Same value everywhere

The flag is on, or off, in every environment with no segment rules. A switch that never differs is not switching anything.

Signal

Never read

Usage reports show no evaluations for a long time. Nobody is asking the flag anything, so the code may already be gone.

Signal

No owner

Nobody claims it. Ownerless flags are almost always forgotten ones.

Signal

Past its removal date

A flag that has outlived its own deadline is the clearest candidate of all.

Signal

Closed ticket

The linked work item is finished, yet the flag remains.

Tools you can use

Flagsmith offers several features that help with detection, though the exact names and availability differ by version and plan, so check your own account. Typical helpers include tags and the ability to mark a flag as stale, an archive option that hides retired flags from everyday lists, flag usage reporting from SDKs, an audit log of every change, and integrations that link flags to code hosting and issues. Some versions can also scan code repositories to show where a flag is referenced, which directly answers the question “is this still used anywhere?”

Use the API for custom reports

For anything the dashboard does not offer, the REST API lets you read every flag with its tags, creation date and state across environments. A small script can build a report of every release flag older than ninety days that is identical in all environments and has no segment rules. That single list is often the most productive cleanup backlog a team can have.

Cross-check before you trust a signal

No single signal proves a flag is dead. A flag that is never read might guard a rarely used report. A flag that has not changed for a year might be a valuable kill switch. Treat the signals as a way to build a short list, then confirm each flag with a person and with a code search before acting.

Analogy

A librarian deciding which books to retire looks at when each was last borrowed, whether newer editions exist and whether anyone has asked for it recently. None of these facts alone settles the matter, but together they make a good shortlist, which the librarian then checks by hand.

9Measuring Flag Debt

What gets measured gets managed. A handful of simple numbers tells you almost everything.

Five numbers worth tracking

MeasureWhat it tells youHealthy direction
Total number of flagsThe overall size of the problemStable or slowly falling
Share of flags older than a set ageHow much of the list is likely staleFalling
Share of flags with an owner tagHow well responsibility is recordedApproaching one hundred percent
Flags created versus flags removed each monthWhether debt is growing or shrinkingRemoved at least equals created
Flags past their removal dateHow well deadlines are honouredNear zero

The most important ratio

If you track only one thing, track the monthly balance between flags created and flags removed. If you create thirty and remove ten, you gain twenty flags of debt every month, and the list will double within a year. If you remove as many as you create, the list stays steady however busy you are. This single ratio turns a vague worry into a clear target.

flowchart LR
  C["Flags created each month"] --> B{"Compare"}
  R["Flags removed each month"] --> B
  B -->|"Created greater than removed"| G["Debt growing: schedule cleanup"]
  B -->|"About equal"| S["Debt stable: keep the habit"]
  B -->|"Removed greater than created"| D["Debt shrinking: good progress"]
Figure 2. The balance between flags created and flags removed shows whether debt is growing or shrinking.

Put the numbers where people can see them

Numbers hidden in a spreadsheet change nothing. Publish them on a team page, include them in a monthly review, and celebrate improvements. A simple chart that shows the flag count by month is enough to start conversations. When the line rises steadily, people notice, and noticing is the first step of repayment.

!
Tip

Choose targets you can reach. “No flags older than ninety days” may be impossible on day one. “Cut the number past their removal date in half this quarter” is achievable, visible and motivating.

10Deciding What to Remove: A Triage Method

Not every old flag should go, and not every flag should go at once.

Sort candidates into four boxes

Once you have a shortlist, sort each flag into one of four boxes. This takes a few minutes per flag and prevents most mistakes.

Box one

Remove now

Fully rolled out, same value everywhere, owner agrees, and no reason to keep a way back. These are the easy wins.

Box two

Remove after a short wait

Recently completed. Keep the flag a little longer as a safety net, with a firm date to remove it.

Box three

Keep, but label properly

Genuinely long-lived switches such as kill switches and entitlements. Tag them as permanent, assign owners and schedule reviews.

Box four

Investigate first

Nobody knows what it does. Find out before touching it, by reading code, checking usage and asking around.

Questions that decide the box

  • Is the flag on or off for everyone, in every environment? If yes, one path of code is dead.
  • Which path is dead? If the flag is on for everyone, the “off” code can go. If it is off for everyone, the feature was abandoned and the “on” code can go.
  • Is there any reason to switch it back? A recently launched feature may still need an emergency way back.
  • Does anything else depend on it? Other flags, reports, partners or scheduled jobs may read it.
  • Who owns it, and do they agree? If the owner is unknown, escalate before acting.

Ranking by value and safety

Start with flags that are easy to remove and costly to keep: old, fully rolled out, in busy parts of the code. Leave the tricky ones for later, once the team has built confidence and routines. Quick, safe wins create momentum, and momentum is what makes cleanup a habit instead of a one-off campaign.

Analogy

When clearing a loft, you first throw away the obvious rubbish, then set aside things to donate, then label boxes to keep, and only then spend time on the mystery boxes. Starting with the mystery boxes would exhaust you before making any progress.

!
Watch out

Never delete a flag just because it looks old. Old and unused are different things. Confirm with usage data, code search and the owner before removing anything from production.

11The Safe Removal Process, Step by Step

The order of operations matters. Removing things in the wrong order is how outages happen.

sequenceDiagram
  participant O as Owner
  participant C as Code
  participant F as Flagsmith
  participant M as Monitoring
  O->>F: Confirm final value in every environment
  O->>C: Remove flag checks and the dead code path
  C->>C: Update tests and default values
  C->>M: Release and watch graphs
  M-->>O: Quiet period passes with no problems
  O->>F: Archive the flag
  F-->>O: Hidden from everyday lists, easy to restore
  O->>F: Delete the flag after a final wait
Figure 3. Code first, then archive, then delete, with watching in between.

The steps in detail

1

Confirm the final truth

Check the flag’s value in every environment and every segment rule. Decide which behaviour is the winner and make sure it is what you want everywhere.

2

Search for every use

Search all code repositories, including mobile apps, web code, backend services and scripts. Remember that old mobile versions still read the flag.

3

Remove the checks and the dead path

Keep the winning behaviour as plain code. Delete the losing branch and any helper functions only it used.

4

Tidy tests and defaults

Simplify tests that toggled the flag, and remove its entry from default values and documentation.

5

Release and watch

Ship the change in a normal release. Watch error rates and key business graphs, just as you would for any change.

6

Wait through a quiet period

Keep the flag in Flagsmith while you wait. Long enough to cover one full business cycle, such as a week or month-end, is wise.

7

Archive

Archiving hides the flag from everyday lists but keeps it available for restoration if something unexpected appears.

8

Delete and close out

After a further wait, delete the flag, along with its overrides, and close the ticket with a short note of what was done.

Why code comes before the dashboard

A common mistake is deleting the flag in the dashboard first because it is the quickest step. If any code still reads the flag, that code now gets a missing value and falls back to its default, which may silently flip behaviour for real users. Removing the code first means the flag is already unnecessary when it disappears.

Why archive before delete

Archiving is a gentle step. If a forgotten report or an old app version still depends on the flag, the failure will appear, you will notice, and you can restore the flag within seconds. Deleting is permanent, so it deserves a pause and a final check.

Analogy

Before demolishing a wall, a builder confirms it carries no load, switches off the wiring, removes fixtures, and only then knocks it down. Nobody starts with the hammer. Removing a flag is demolishing a wall inside a live building.

12The Code Side: Removing Flag Checks Cleanly

Most of the cleanup effort lives in code, not in the dashboard.

What a flag check looks like in spirit

In plain terms, a flag check is a fork: “if the flag is on, do the new thing, otherwise do the old thing.” Removal means choosing the winner of that fork, keeping its code, and deleting the other path together with the fork itself. When the flag is fully on, you keep the new path. When the flag was abandoned and is off, you keep the old path.

Common shapes of flag use

Shape

Simple branch

One check, two paths. The easiest to remove: keep one path, delete the other.

Shape

Nested checks

A flag inside another flag’s branch. Remove the inner ones first, then the outer, and test after each step.

Shape

Checks scattered across files

The same flag read in many places. A thorough code search is essential, and a single list of usages helps.

Shape

Flag value passed around

The flag is read once and the result travels through functions. Follow the value to every place it changes behaviour.

Shape

Config values

A text or number flag. Replace the lookup with a fixed value or a normal setting in your own configuration.

Shape

Multivariate flags

Several variations of a feature. Keep the winning variation and remove all the rest, with their code.

Habits that make removal safe

  • Isolate flag checks. Keep each flag read in as few places as possible, ideally one decision point, so removal touches little code.
  • Prefer small, separate changes. Remove one flag per change, so a problem points at one cause.
  • Let tests lead. Make sure the winning path is well covered by tests before deleting the losing path.
  • Remove helpers too. Functions, styles and assets used only by the dead path should go with it.
  • Let tools help. Linters and static analysis can flag unreachable code after the check is removed.
Analogy

Removing a railway junction means choosing which track to keep, lifting the other one and the switch that joined them, and updating the signal diagram. If you lift the track but leave the signals, the next driver is confused. The code that decided and the code that was decided between must both go.

!
Tip

Write flag checks so that the old behaviour is a clearly separate block. When the day of removal comes, deleting a clearly marked block is far less risky than untangling a mixed one.

13The Flagsmith Side: Archive, Delete, Overrides and Environments

What to do in the dashboard once the code is clean.

Archiving

Flagsmith lets you archive a flag. An archived flag is hidden from normal lists, which reduces clutter, but it is not destroyed. Archiving is ideal as a holding area: it signals “this is retired” to everyone, while keeping the option of bringing it back. The exact behaviour of archived flags in SDK responses can differ, so confirm in the documentation for your version, and test with a non-production flag first.

Deleting

Deleting removes the flag and its states permanently. Its history in the audit log remains, which is valuable: months later, someone can still learn when and by whom a flag was removed. Delete only after the quiet period has passed, and make sure the owner has signed off.

Overrides: the hidden leftovers

Segment overrides give a flag special values for groups of users. Identity overrides give special values to individual users. Both are easy to forget. When a flag is deleted, its overrides disappear with it, but while the flag is alive they continue to influence results. Before retiring a flag, review its overrides, because they may reveal users or groups that still depend on the old behaviour.

Environments

Check every environment. A flag may be long finished in production but still used in a staging test or an old demo environment. If you remove it everywhere at once, those places may break. Either update them in advance or accept that they will use defaults and fix them as they appear.

Segments left behind

Segments are reusable groups, such as “beta testers.” After removing a flag, the segment may now be unused. Review segments too, since an old segment that no flag uses is a small piece of debt of its own. Take care, though: a segment might be used by other flags, so check before deleting.

ItemQuestion to askAction
FeatureIs any code still reading it?Archive, wait, then delete
Feature statesDo all environments agree on the winner?Confirm before deleting
Segment overridesDoes any group still depend on special behaviour?Review, then let them go with the flag
Identity overridesAre any real users specially treated?Check with the owner before deleting
SegmentsIs any other flag using this group?Delete only if unused everywhere
TagsAre they still meaningful?Tidy occasionally
!
Watch out

Deleting is not undoable in the way archiving is. If you are unsure, archive and wait. Waiting costs a little clutter. A wrong deletion can cost an outage.

14Special Case: Experiments and Multivariate Flags

Flags with several versions need an extra step: choosing the winner.

Why experiments are tricky

A normal release flag has two states. An experiment has several variations, each shown to a share of users. When it ends, you must decide what happens to every user who was in a variation. The winner becomes the only behaviour. The losers are removed. Skipping the decision leaves users permanently split into groups nobody is studying.

A clean ending for an experiment

1

Stop collecting

Decide in advance how long the experiment runs and how many users it needs, then stop when that point is reached.

2

Record the result

Write down what was tested, what was learned and which variation won, in a place the whole team can find.

3

Roll the winner to everyone

Move one hundred percent of users to the winning variation and confirm the graphs stay healthy.

4

Remove the losers

Delete the code, styles and assets for the losing variations.

5

Retire the flag

Follow the normal archive and delete process, and tell the analytics team so old charts remain understandable.

Keep the analytics story intact

If your analytics tools received flag states as user properties, those properties will stop updating when the flag is removed. Make a note in the analysis documents, so that someone studying data next year understands why the property disappears on a certain date, and which variation became the default from then on.

Analogy

A taste test at a market ends when the stall owner picks a recipe, writes it on the menu and takes the other samples off the table. Leaving every sample out forever would make it impossible to know what the shop actually sells.

!
Tip

Put the experiment’s end date and decision owner into the flag description at creation. An experiment with a named owner and a date finishes. One without drifts on indefinitely.

15Special Case: Mobile Apps and Old Versions

On phones, old code never really dies.

The long tail of app versions

On a server, you control when new code runs. On a phone, users update when they feel like it. Some never do. This means that for months or years, versions of your app that still read an old flag may keep running on real devices. If you delete the flag the moment your newest version stops using it, those old versions may behave unpredictably.

What happens to old versions

When an old app asks for a flag that no longer exists, the SDK returns nothing, and the app falls back to its built-in default. If the default was chosen sensibly, the old app simply shows its old behaviour. If the default is the opposite of what the flag had been saying, those users suddenly see the feature disappear or appear, which can be confusing or even harmful.

A safe approach

  • Check how many users run old versions. Use analytics to see which versions are still active.
  • Keep the flag until old versions fade. If a meaningful number of users run a version that reads the flag, keep the flag alive in its final state until they upgrade or you retire support.
  • Choose defaults that match the final state. For future versions, set the default to the winning behaviour so removal changes nothing.
  • Use a version trait. Send the app version as a trait, so you can target or exclude old versions precisely.
  • Consider forced upgrades. If very old versions block cleanup, a gentle upgrade prompt can help.
SituationRisk of deleting nowBetter action
Only the latest app version reads the flagLowFollow the normal removal process
Older versions with many users still read itHighKeep the flag in its final state until they fade
Older versions have a default opposite to the final stateHighKeep the flag, or wait for those versions to retire
Web code only, always latestLowRemove after a normal quiet period
Analogy

A city can replace all its road signs in a weekend, but it cannot replace the printed maps people already carry in their glove boxes. Old maps keep sending drivers down roads you have changed. Old app versions are the old maps in the glove box.

16Automating the Boring Parts

Cleanup that depends on remembering will fail. Cleanup that machines remind you about will not.

What can be automated

Report

Monthly stale-flag report

A script reads all flags through the API and lists those past their removal date, ownerless, or identical everywhere, grouped by owning team.

Nudge

Reminders to owners

The report posts a polite message to each team’s chat channel: “These four flags are past their removal date. Are they still needed?”

Gate

Rules at creation

A pipeline check refuses to create a release flag without an owner tag and a removal date.

Tag

Automatic stale labels

A job marks suspicious flags with a “cleanup-candidate” tag, making them easy to find and discuss.

Detect

Code search

A scheduled search lists flags that no longer appear in any repository, which is strong evidence of a dead flag.

Export

Snapshots

A nightly export saves the state of all flags, so you can compare, restore or audit later.

flowchart TD
  S["Scheduled job each week"] --> L["Read all flags through the REST API"]
  L --> F["Filter: past removal date, no owner, same value everywhere"]
  F --> T["Tag cleanup candidates"]
  T --> R["Build report grouped by team"]
  R --> N["Post to team chat channels"]
  N --> H["Owners decide: remove, extend or mark permanent"]
  H --> U["Record decision in flag description"]
Figure 4. A weekly job finds candidates and sends them to owners, who decide.

Automation advises, humans decide

Resist the urge to delete automatically. A script that archives or deletes flags on its own will eventually remove something important. Let automation find candidates, label them and nag owners, while people make the final decision. If you do automate archiving, restrict it to flags that meet strict, well-tested conditions, and always run a dry run first.

Use least privilege for cleanup robots

A reporting script needs only read access. A tagging script needs permission to edit tags. A script that archives needs a little more. Give each job its own named key with only the permissions it needs, so the audit log shows exactly which robot did what, and a mistake cannot cause more damage than its role allows.

!
Watch out

Make scripts safe to run twice. They should set a desired state, such as “tagged as candidate,” never toggle something on and off. Reruns after a crash must do no harm.

17Organising the People Side: Ownership and Rituals

Technical debt is a people problem wearing technical clothes.

Who owns cleanup?

The creator of a flag should own its removal. This is the simplest and most effective rule. It keeps responsibility close to knowledge, since the person who made the flag knows best why it exists. When the creator leaves or changes teams, ownership passes to the team, not to the void. That is why the owner tag names a team, not just a person.

Rituals that make cleanup normal

Weekly

Five-minute flag glance

During a regular team meeting, look at the list of flags past their removal date. If it is empty, celebrate. If not, assign each one.

Per release

Cleanup in the definition of done

A feature is not finished until its flag is removed, or the removal is scheduled with a date.

Monthly

Debt report review

Look at the created-versus-removed balance and the age profile, and discuss trends.

Quarterly

Cleanup day

A shared, time-boxed session where teams retire their candidates together, with snacks and recognition.

Make removal respected work

Cleanup rarely wins praise, because nothing visible ships. Change that. Mention flag removals in team updates. Count them in planning. Treat a deletion that makes a file simpler as an achievement. When removal is respected, it gets done. When it is treated as a chore for later, it never is.

Budget some time for it

Reserve a small, steady share of each team’s time, such as a few percent, for cleanup and maintenance. This keeps debt from compounding and avoids the awkward bargaining over every single cleanup task. A modest regular allowance beats a large occasional campaign.

Analogy

A restaurant kitchen is cleaned a little at every shift and deep-cleaned on a schedule. A kitchen cleaned only when the inspector visits is always one bad day from closure. Regular, small, shared cleaning is the cheapest way to stay safe.

!
Tip

Make the first cleanup day easy and rewarding. Pick fifteen obvious flags, finish them in an afternoon, and share the results. Early success builds trust in the process.

18Security, Permissions and Audit During Cleanup

Cleanup changes production, so it deserves the same care as any other change.

Permissions

Not everyone should be able to delete flags. A sensible arrangement lets many engineers view flags, a smaller group archive and delete them, and reserves administrative actions for a few trusted people. This follows the principle of least privilege: each person and each robot gets only the access the job requires.

Approval for risky removals

For flags that touch critical paths such as payments or login, require a second person to review the removal plan. Some Flagsmith plans offer change approval workflows. Where they are not available, a pull request on the code change and a short checklist in the ticket achieve the same discipline.

The audit log as your safety record

Every change, including archive and delete, is written to the audit log with who made it and when. This gives you a trustworthy history for incident reviews and for audits. It only works if identities are meaningful, so avoid shared logins and give each automation its own named key.

Keys and secrets

Cleanup scripts use powerful credentials. Keep them in a secrets manager, never in repositories or chat messages, rotate them on a schedule, and revoke them when a script is retired. A forgotten cleanup key with delete permission is a hazard of its own.

RiskExampleSimple defence
Wrong deletionA kill switch removed because it looked unusedKind tags, owner approval, archive before delete
Over-powerful scriptReporting job with delete permissionLeast-privilege keys per job
No accountabilityShared login hides who deleted a flagPersonal accounts and named keys
Leaked keyCleanup key committed to a repositorySecrets manager, scanning, quick rotation
Silent breakageOld app versions lose a flag they relied onCheck version usage, keep final-state flags
Analogy

In a hospital, throwing away old medicine is done by authorised staff, logged, and checked against records. Nobody doubts the nurses. The routine simply ensures that an expired bottle goes in the bin and an important one does not.

19Monitoring and Watching After a Removal

A removal is a change, and every change deserves a few minutes of attention afterwards.

What to watch

  • Error rates in the services touched by the change.
  • Key business graphs such as sign-ups, orders or successful payments.
  • Fallback and default usage in SDK logs, which can reveal code that still reads the removed flag.
  • Support tickets and user reports in the day or two following.
  • Old app version behaviour, if mobile clients are involved.

Use markers on dashboards

Flagsmith integrations can push flag change events to monitoring tools, so that archive and delete actions appear as markers on your graphs. If a metric changes right after a marker, you know where to look first. Make sure cleanup robots have clear names so the markers explain themselves.

A short watch routine

1

Minutes after release

Check error rates and the key graphs for anything unusual.

2

Hours after release

Look at support channels and logs for missing-flag warnings.

3

Days after release

Confirm the quiet period passed with no problems before archiving.

4

Weeks after archiving

Confirm nothing tried to restore or read the flag, then delete it.

Know how to go back

Decide your way back before you start. If the code removal causes trouble, the usual path is to revert the release. If the flag was archived, unarchive it. Because flags are switches, a restored flag with its final value is usually enough to bring the old behaviour back quickly while you investigate calmly.

!
Tip

Write the reversal steps in the ticket before starting. A rollback plan written in a calm moment is worth ten written during an incident.

20Design Patterns and Anti-Patterns

Habits that keep flag debt low, and habits that quietly build it.

Patterns worth copying

Pattern

Flag with an expiry

Every temporary flag is born with an owner, a kind and a removal date.

Pattern

Cleanup in the definition of done

A feature is not complete until its flag is removed or the removal is scheduled.

Pattern

Single decision point

Each flag is read in one place in code, so removal touches little.

Pattern

Created-versus-removed balance

The team watches the monthly balance and keeps it level or falling.

Pattern

Archive, wait, delete

A gentle retirement path that allows a quick way back.

Pattern

Automated nudges

Scripts find candidates and remind owners, and people make the decisions.

Advantages and trade-offs of regular cleanup

Advantages

  • Simpler code that new teammates understand quickly.
  • Fewer combinations to test and fewer hidden bugs.
  • Lower operational risk from forgotten switches.
  • A clean, trusted flag list in the dashboard.
  • Faster changes, because less history must be understood first.

Trade-offs

  • Time spent that ships no visible feature.
  • A small risk with every removal, managed by process.
  • Need for tags, owners and reports, which take upkeep.
  • Occasional disagreement about whether a flag is still needed.
  • Extra care required for mobile apps and old versions.

Anti-patterns to avoid

ANTI-PATTERN 01Avoid
What people do

They create flags with vague names and no owner, intending to “sort it out later.”

Why it hurts

Later never comes. Months afterwards, nobody can tell what the flag does or who may remove it, so it stays forever.

Better approach

Require a clear name, a description, an owner tag and a removal date at creation.

ANTI-PATTERN 02Avoid
What people do

They delete flags in the dashboard first because it is quick, before removing the code.

Why it hurts

Code still reading the flag now receives a missing value and silently falls back to a default, which may change behaviour for real users.

Better approach

Remove code first, release, wait, archive, and only then delete.

ANTI-PATTERN 03Avoid
What people do

They reuse an old flag name for a new purpose to save time.

Why it hurts

Old code, old overrides and old app versions may still react to the name, producing behaviour nobody intended. This pattern is behind some of the best-known flag-related incidents.

Better approach

Always create a fresh flag with a new name, and fully retire the old one.

ANTI-PATTERN 04Avoid
What people do

They run a one-time heroic cleanup, then go back to creating flags carelessly.

Why it hurts

The list is clean for a month and then grows again. Effort is wasted because the causes were never addressed.

Better approach

Fix creation habits and add small, regular rituals so the list stays clean.

ANTI-PATTERN 05Avoid
What people do

They use permanent flags to hide permanent differences, such as customer-specific behaviour, without calling them configuration.

Why it hurts

These flags look like debt but cannot be removed, so they get deleted by mistake or ignored forever, and nobody knows which is which.

Better approach

Tag long-lived flags as permanent, give them owners, and review them on a schedule.

21Best Practices and Common Mistakes

A practical checklist drawn from everything so far.

Do these

  • Tag every flag with an owner and a kind when it is created.
  • Give temporary flags a removal date and a linked ticket.
  • Schedule removal at the moment of full rollout, while memory is fresh.
  • Measure the created-versus-removed balance every month.
  • Remove code first, then archive, wait, and delete.
  • Review overrides and environments before retiring a flag.
  • Handle old mobile versions deliberately.
  • Let automation find candidates and let people decide.

Common mistakes and quick cures

MistakeWhat you seeCure
No owner tagHundreds of flags nobody claimsMake the owner tag mandatory at creation
No removal dateTemporary flags live for yearsAdd a date and a linked cleanup task
Deleting before removing codeSurprise behaviour changes after deletionFollow the code-first order
Forgetting identity overridesA few users are treated oddly long after cleanupReview overrides before retiring the flag
Treating kill switches as clutterThe emergency switch is gone when neededTag permanent flags and review them separately
Ignoring old app versionsComplaints from users on older releasesCheck version usage before deleting
Cleanup only in campaignsThe list grows back within monthsBuild small weekly and monthly habits
The best flag cleanup is the one that happens so regularly nobody remembers it was ever a problem.

22A Worked Example: A Streaming Company Pays Down Its Flag Debt

A made-up company shows how the pieces fit together.

The story below is hypothetical. Imagine a video streaming company called Blue Harbor, with a mobile app, a web player and ten backend services. After four years, Flagsmith shows 1,100 flags. Nobody can say how many matter. A new engineering manager decides to bring order.

Step one: make the debt visible

An engineer writes a read-only report using the Flagsmith API. It lists every flag with its age, tags, values in each environment and whether it has segment rules. The shocking numbers: 640 flags have no owner tag, 520 are older than a year, and 410 have the same value in every environment.

Step two: agree on kinds and rules

The teams agree on four kinds: release, experiment, operational and permission. They agree that every new flag needs an owner tag, a kind tag and, for temporary kinds, a removal date. A pipeline check enforces the rule from that day on.

Step three: triage the easy wins

The report is filtered to release flags, older than a year, identical everywhere, with no segment rules. That produces 260 candidates. A weekly job tags them “cleanup-candidate” and posts lists to each team’s channel, asking owners to confirm.

Step four: investigate the mysteries

For 180 flags with no owner, a code search shows that 120 are not referenced anywhere in any repository. The platform team archives those after a short announcement, keeping them restorable for a month. The other 60 are still referenced and go into an investigation box.

Step five: careful with mobile

Analytics show that 8 percent of mobile users still run versions from two years ago. Flags read by those versions are kept in their final state, and tagged “keep until version retired.” The team schedules a gentle upgrade prompt for those users.

Step six: remove in small batches

Developers remove flag checks in small changes, one flag per change, with tests. After each release, graphs are watched. One removal reveals a rarely used report that still read a flag. The flag is restored from archive in seconds, tagged as long-lived, and given an owner.

Step seven: delete and learn

After a month without surprises, the archived flags are deleted. The audit log records every deletion against a named cleanup key. The team writes a short note about what they learned, including the rarely used report.

Step eight: make it a habit

The team sets a rule that flags created each month must be matched by flags removed. A five-minute weekly glance at overdue flags, a monthly debt review and a quarterly cleanup day keep the list steady. Within six months the total falls from 1,100 to 380, and every remaining flag has an owner.

What made this smooth

Nothing needed heroics. The team made debt visible, agreed on simple rules, let machines find candidates and humans decide, protected old app versions, and watched after every removal. Each small habit covered a different risk, and together they turned an intimidating mess into a routine chore.

23The Same Idea in the Wider World

Every growing system faces the same quiet decay. Learning from other fields makes the lesson stick.

Flag debt is one example of a much older pattern: things that are easy to add and hard to remove accumulate until they hurt. The examples below describe publicly known practices in general terms, not any company’s private systems.

Software

Dead code

Code that can never run still costs reading time and testing effort. Engineering teams use tools and reviews to find and remove it regularly.

Software

Deprecated features

Large platforms announce retirements long in advance, give timelines, and keep old versions alive for a while, just as old app versions should be treated here.

Operations

Unused cloud resources

Teams regularly hunt for forgotten servers, disks and accounts that still cost money and expand the attack surface.

Security

Stale accounts and keys

Security programmes review old accounts and credentials, because forgotten access is a classic route for trouble.

Data

Retention policies

Organisations delete data after a set period instead of keeping everything forever, reducing both cost and risk.

Everyday life

Subscriptions

Many people discover old subscriptions they forgot. A periodic review is the cure, and the same is true for flags.

The shared pattern

Across all of these, the same few habits keep appearing. Record who owns each thing. Give temporary things an end date. Measure how much exists. Review on a schedule. Retire gently, with a way back. Make removal respected work. Teams that follow these habits in one area find it easy to apply them in another.

Analogy

A well-run library does not keep every book forever, nor does it discard books at random. It records what it owns, checks how often each is borrowed, moves rarely used books to storage, and withdraws those that are truly outdated. Flag management follows the same quiet librarian’s logic.

Lessons you can reuse

  • Plan the end of a thing on the day it begins.
  • Keep an inventory with owners.
  • Prefer small, regular tidying over occasional crisis cleaning.
  • Retire in stages so mistakes can be undone.
  • Measure the trend, not just the total.
What is cheap to create and free to keep will always pile up, unless someone decides otherwise.

24Limits: What Cleanup Cannot Do

Knowing the limits of any practice is as valuable as knowing its strengths.

It cannot replace good creation habits

No amount of cleanup will keep up with careless creation. If flags keep appearing without owners and dates, you will always be digging out. Prevention and cleanup are two halves of one habit.

It cannot be fully automated

Machines can find candidates, but only people can judge whether a flag still matters. Business context, customer promises and upcoming plans live in human heads. Treat automation as a flashlight, not a bulldozer.

It cannot remove risk entirely

Every change carries some risk, including removal. Process reduces the risk but does not erase it. That is why small steps, quiet periods, watching and rollback plans matter.

It cannot fix poorly structured code

If flag checks are scattered across hundreds of files, removal will be slow however well planned. Cleanup reveals structural problems, and fixing them is a separate, longer task. Improve how flags are read in code so future removals are easier.

It is not a substitute for deleting features that should never have shipped

Sometimes a flag marks a feature that is genuinely abandoned. The right answer is to remove the feature entirely, not to keep a switch that can never matter. Product decisions and flag decisions should be made together.

You want toDoDo not
Stop debt from growingFix creation habits with owners and datesRely on occasional campaigns
Find stale flagsCombine usage data, age, owners and code searchTrust a single signal
Retire a flagCode first, then archive, wait and deleteDelete in the dashboard first
Handle kill switchesTag as permanent and review regularlyTreat as clutter
Speed up cleanupAutomate reports and remindersAutomate deletion without review
!
Tip

If a cleanup task feels impossible, shrink it. One flag, one change, one release. Small steps are how every large pile eventually disappears.

25A Ninety-Day Plan, a Runbook and a Cheat Sheet

Three practical tools to keep beside your team’s notes.

Part one: a ninety-day plan

Days 1 to 30

See the debt

Build a read-only report of all flags with age, tags and values. Agree on kinds and owner tags. Make owner and kind mandatory for new flags. Publish the baseline numbers.

Days 31 to 60

Harvest the easy wins

Triage release flags that are old and identical everywhere. Remove the checks in small changes, archive after a quiet period, and delete. Start the weekly glance at overdue flags.

Days 61 to 90

Make it automatic

Schedule weekly reports and owner nudges, add pipeline rules, set the created-versus-removed target, and hold the first quarterly cleanup day.

Part two: a removal runbook

A runbook is a short, step-by-step guide that a tired person can follow. Here is one for retiring a single flag.

1

Confirm kind and owner

Make sure the flag is a temporary kind and the owner agrees to the removal.

2

Confirm final value everywhere

Check every environment, segment rule and identity override. Decide the winning behaviour.

3

Search all code

Include mobile, web, backend, scripts and tests. Check which app versions read the flag.

4

Remove code and tidy

Keep the winning path, delete the rest, simplify tests and remove the default value.

5

Release and watch

Ship normally and watch errors and key graphs.

6

Archive after the quiet period

Hide the flag from lists while keeping it restorable.

7

Delete and record

Delete the flag, close the ticket and write a one-line note of what was done.

Part three: a one-page cheat sheet

  • Tag at birth. Owner, kind and removal date, always.
  • Plan the end. The removal task is created with the flag.
  • Measure the balance. Created versus removed, every month.
  • Find by many signals. Age, sameness, usage, owners, code search.
  • Triage into four boxes. Remove now, remove soon, keep and label, investigate.
  • Code first. Then release, archive, wait and delete.
  • Mind the leftovers. Overrides, segments, environments and old app versions.
  • Automate the nudges. Humans make the decisions.
  • Protect kill switches. Label them permanent and review them.
  • Keep it small and regular. A little every week beats a campaign every year.

Pin this list beside your team’s runbook. New joiners can read it in two minutes, and experienced engineers will find that it settles most arguments quickly. Good habits around cleanup are what turn a fast-growing flag programme into a lasting asset instead of a slowly collapsing pile.

One last piece of advice concerns patience. Nobody clears four years of debt in a week. Begin with the easy wins, build routines, and let the numbers show your progress. Teams that clean gradually and consistently end up with simpler, safer systems than teams that wait for a perfect moment, because every removal is justified by a real flag they have already examined.

26A Plain-English Glossary

Quick definitions of the words used in this guide.

Term

Feature flag

A switch in software that decides whether a feature is visible.

Term

Technical debt

Extra future work caused by shortcuts or neglect, with ongoing interest in the form of slowdowns and risk.

Term

Flag debt

The build-up of old, unneeded flags that make code harder to understand and test.

Term

Stale flag

A flag that has stopped doing useful work but still sits in code and dashboard.

Term

Release flag

A temporary flag used to ship and roll out a feature safely.

Term

Experiment flag

A flag that splits users to compare versions until a winner is chosen.

Term

Kill switch

A long-lived flag kept to turn off risky behaviour quickly.

Term

Permission flag

A flag that decides who gets which paid or special features.

Term

Environment

One stage of a project, such as development, staging or production.

Term

Segment override

A special flag value for a group of users.

Term

Identity override

A special flag value for one individual user.

Term

Tag

A label attached to a flag, such as its owner or kind, used for finding and filtering.

Term

Archive

Hiding a flag from everyday lists while keeping it restorable.

Term

Audit log

The official diary of who changed what and when.

Term

Least privilege

Giving each person or robot only the access the job needs.

Term

Runbook

A short, step-by-step guide for a routine or an emergency task.

Term

Idempotent

Safe to repeat: doing it twice has the same effect as doing it once.

Term

Dead code

Code that can never run, but still has to be read, tested and maintained.

27Making the Business Case for Cleanup

Cleanup competes with new features for time. Here is how to win that argument fairly.

Speak the language of cost and risk

Managers rarely respond to “the code is messy.” They respond to cost, speed and risk. Translate flag debt into those terms. Cost: how many engineer-hours are spent each month working around old flags, explaining them to newcomers, or testing combinations that should not exist. Speed: how much longer changes take in areas crowded with flags. Risk: how many critical paths contain switches nobody understands.

Estimating the interest

You do not need exact figures. A rough estimate is enough to start a conversation. Ask a few engineers how many minutes a week they lose to flag confusion, multiply by the number of people, and convert to hours per month. Then compare that with the hours needed to remove the oldest hundred flags. Very often the one-time cost of removal is repaid within a few months.

ItemExample estimateHow to gather it
Time lost per engineer per weekAbout 30 minutesShort anonymous survey
Engineers affected40Team size in flag-heavy areas
Monthly interest paidAbout 80 hoursMultiply and convert
One-time cost to remove 100 flagsAbout 100 to 150 hoursTime a few trial removals
Payback periodRoughly 1 to 2 monthsDivide cost by monthly interest

These numbers are only an illustration, and your own will differ. The point is the method: make the cost visible, compare it with the cost of the cure, and let the comparison speak.

Tell stories, not only numbers

A single memorable incident is worth a page of statistics. If a confusing flag once delayed a release by a day, or caused a short outage, tell that story plainly and without blame. People remember stories, and stories turn an abstract worry into a concrete reason to act.

Analogy

Servicing a car feels like a nuisance until you compare its small, regular cost with the price of a broken engine. Nobody argues that servicing is exciting, but nearly everyone agrees it is cheaper than ignoring it. Flag cleanup is the regular service for your codebase.

Ask for something small first

Do not ask for a six-month programme. Ask for one afternoon, one team and one clear measure of success. When that small trial shows fewer flags, simpler code and no incidents, the next request is much easier. Credibility is built one small success at a time.

Connect cleanup to goals people already care about

  • Faster delivery. Simpler code means shorter changes and fewer surprises during release.
  • Reliability. Fewer unknown switches means fewer unplanned incidents.
  • Onboarding. New hires become productive sooner when the codebase tells a clear story.
  • Security and compliance. A clean inventory with owners makes audits easier.
  • Cost. Less dead code and fewer unused resources reduce effort and spending.
!
Tip

Report cleanup results in the same meetings where feature results are reported. When removal sits beside launches in the update, it is seen as real work.

28Dashboards and Reports for Flag Health

A small, honest dashboard keeps the whole team aware of the state of the drawer.

What a flag health page should show

You do not need a fancy tool. A single page, refreshed weekly by a script, is enough. It should answer five questions at a glance: how many flags exist, how old they are, who owns them, which are past their removal date, and whether the list is growing or shrinking.

Chart

Flag count over time

A simple line by month. A rising line is the earliest visual warning that creation is outrunning removal.

Chart

Age profile

How many flags fall into each age band, such as under thirty days, up to ninety, up to a year, and older.

Table

Overdue flags by team

A short list grouped by owner, so each team sees only what it must act on.

Number

Ownership coverage

The percentage of flags with an owner tag. The goal is as close to one hundred percent as possible.

Number

Created versus removed

Last month’s balance, with a note on whether the debt is growing, steady or shrinking.

Table

Permanent flags review

Kill switches and entitlements with their last review date, so none is forgotten.

flowchart LR
  A["Flagsmith REST API"] --> B["Weekly report job"]
  B --> C["Compute age, owners, sameness, overdue"]
  C --> D["Store snapshot for trend charts"]
  D --> E["Publish health page"]
  C --> F["Post overdue lists to team channels"]
  E --> G["Monthly review meeting"]
  F --> H["Owners act on their flags"]
Figure 5. A weekly job reads flags, computes health measures, stores a snapshot and shares results with people.

Keep snapshots to see trends

A single report tells you where you are. A series of reports tells you where you are heading. Save a snapshot each week, even if it is just a small file, so you can draw trend lines and show that the work is paying off. Snapshots also help in audits, because they prove what the flag inventory looked like on a given date.

Make the page friendly

A health page nobody reads is wasted. Keep it short, use plain words, show the trend first and the lists second, and link each flag to its place in Flagsmith and its ticket. Avoid blaming individuals. Group by team, and phrase it as an invitation: “These five flags are ready for retirement.”

Beware of vanity numbers

A falling total looks good, but it can be gamed: archive flags instead of cleaning code, and the count drops while the debt remains. Pair the flag count with a measure that reflects real code removal, such as the number of flag checks found by a code search. If the number of checks in the code falls along with the flag count, the improvement is real.

!
Watch out

Do not set targets that reward the wrong behaviour. If people are praised for reducing the count at any cost, they may delete flags carelessly. Praise safe, well-tested removals, and celebrate the absence of incidents as much as the drop in numbers.

A small set of questions for the monthly review

  • Did we create more flags than we removed? If so, why?
  • Which team has the most overdue flags, and what is blocking them?
  • Are any permanent flags overdue for review?
  • Did any removal cause a surprise, and what did we learn?
  • What is the single most valuable flag we could retire next month?

Ten minutes on these questions each month keeps the practice alive. The aim is not perfection. It is steady attention, and steady attention is what stops the drawer from filling with keys again.

Five questions to ask before you create any flag

Prevention is the cheapest cleanup. Before creating a new flag, pause for a minute and answer five short questions. Doing so takes almost no time and prevents most of the debt described in this guide.

Question 1

Do we really need a flag?

If the change is tiny, safe and easy to reverse by releasing again, a flag may add more complexity than it removes.

Question 2

What kind of flag is this?

Release, experiment, operational or permission. The answer decides how long it should live and how it will be reviewed.

Question 3

Who owns it?

Name a team, not only a person, so that responsibility survives holidays and job changes.

Question 4

When will it be removed?

Write a date or a condition, such as “thirty days after full rollout,” and open the removal task now.

Question 5

What is the safe default?

Decide what the app does when the flag cannot be read, and make sure that behaviour is the stable, tested one.

These five questions work for a tiny change and for a company-wide programme alike. Teams that make them a habit rarely have dramatic flag problems, because small issues are noticed and fixed while they are still small, long before they can interfere with a launch, an experiment or an incident response.

A culture that tidies as it goes

In the end, flag hygiene is a matter of culture more than tools. In a healthy team, removing a flag is as normal as writing a test. Nobody needs to be asked, because everyone remembers that a feature is not finished until its scaffolding is gone. Leaders set this tone by praising tidy work, by giving time for it, and by never treating cleanup as something done only when there is nothing better to do. Newcomers pick up the habit by watching how the team behaves, which is why the first few weeks of a new engineer are the best moment to show them how flags are created, tracked and retired. A culture like this does not appear overnight, but it grows steadily from small, repeated, visible actions, and it keeps paying back long after the first cleanup day has been forgotten.

Write down what you learn

Every cleanup teaches something. A flag that turned out to guard a rare report, an old app version that still read a switch, a segment that three flags shared: each lesson is worth a sentence. Keep a short shared note of surprises and how they were handled, and link it from your removal runbook. The next person to retire a flag will read it, avoid the same trap and add a lesson of their own. Over a year, that small note becomes the most practical guide your team owns, because it describes your systems, your habits and your history, not someone else’s.

It also helps to say thank you. When a teammate removes a stubborn flag that has haunted a service for years, mention it in the team channel. Recognition is cheap, it is remembered, and it tells everyone that tidy work is valued. People repeat what is noticed and appreciated, and that quiet encouragement does more for flag hygiene than any rulebook or tool ever could.

Finally, keep your expectations realistic and your tone kind. Some flags will turn out to be harder to remove than anyone expected, and some mistakes will happen along the way. Treat each one as information about the system, not as a failure of a person. Blameless reviews, short written notes and a steady rhythm of small improvements will carry a team much further than pressure ever does. The goal is not a perfectly empty flag list. The goal is a list in which every item has a purpose, an owner and a plan, so that nobody ever again has to wonder what a mysterious switch does, or whether it is safe to touch.

If you take only one idea from this guide, let it be that every flag deserves an ending. Decide that ending on the day the flag is born, write it where everyone can see it, and check on it regularly. Everything else in this guide is detail in service of that single, simple promise.

29Frequently Asked Questions

Quick answers to the questions beginners ask most often.

Q1How many flags are too many?
There is no magic number. A better test is whether every flag has an owner, a purpose and a place in the lifecycle. If most flags cannot pass that test, you have too many, whatever the count.
Q2How long should a release flag live?
Typically days to a few weeks after the feature is fully rolled out. Choose a target that fits your team, write it on the flag, and review exceptions.
Q3How do I tell a dead flag from a kill switch?
Look at the kind tag, the description and the owner. A kill switch is designed to stay and is usually off or on by design. Confirm with the owner, because a switch that never changes can be either one.
Q4Should I delete or archive?
Archive first. It hides the flag while keeping it restorable. Delete after a quiet period with no surprises.
Q5What if I cannot find the owner?
Check the audit log for who created or last edited it, search code for hints, and ask in team channels. If nobody claims it, move it to the investigate box, and do not delete it until you understand what it does.
Q6What happens to apps that still read a deleted flag?
They receive no value and fall back to their built-in default. If that default matches the final behaviour, nothing visible changes. If not, users may see a different behaviour, which is why defaults and old app versions matter.
Q7Can I automate the whole cleanup?
You can automate finding candidates, tagging them and reminding owners. Deleting automatically is risky and should be limited to tightly defined cases with dry runs and review.
Q8How do I convince my team to spend time on this?
Show the numbers: how many flags exist, how many are stale, and how much time confusion costs. Start with a small, quick win and share the results. Many teams find enthusiasm grows once the code gets visibly simpler.
Q9Do I need a paid plan for this?
Many cleanup practices, such as tags, descriptions, archiving and API reports, need no special features. Some conveniences, such as approval workflows, may depend on your plan, so check your own account.
Q10What about flags used in many services?
Search every repository, list each service that reads the flag, and coordinate removal so that all services stop reading it before the flag is archived. A shared checklist in the ticket keeps everyone aligned.
Q11How often should we review?
A short weekly glance at overdue flags, a monthly look at the numbers and a quarterly cleanup day suit most teams.
Q12Is it okay to leave a few flags forever?
Yes, if they are deliberate: kill switches and permission flags. Label them as permanent, give them owners and review them on a schedule so they are managed, not forgotten.
Q13What is the single most important habit?
Give every temporary flag an owner and an end date on the day it is created. Almost every other cleanup problem becomes smaller if that one habit is kept.

30Summary and Key Takeaways

The whole guide on one page.

Key Takeaways

  • Flags are cheap to create and costly to keep. Without a plan, they pile up into flag debt that slows reading, testing and releasing, and raises the risk of nasty surprises.
  • Know the four kinds. Release and experiment flags are temporary and must expire. Kill switches and permission flags are long-lived and need owners and reviews.
  • Prevent first. Create every flag with a clear name, a description, an owner, a kind and a removal date, and open the removal task on the same day.
  • Make debt visible. Combine age, sameness across environments, usage, ownership and code search, and track the monthly balance of flags created versus removed.
  • Remove in the right order. Confirm the final value, remove the code, release, wait, archive, wait again, then delete, and review overrides, environments and old app versions along the way.
  • Let machines find, let humans decide. Automate reports, tags and reminders with least-privilege keys, and keep deletion decisions with people.
  • Make it a habit. A short weekly glance, a monthly review and a quarterly cleanup day keep the list small, trusted and safe.