> AI agents: this is one page from PostHog's docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt # Cleaning up – Feature Flags pocket guide Canonical URL: https://posthog.com/learn/feature-flags/pocket-guide/cleanup ## On this page - [Let the rollout state decide](#let-the-rollout-state-decide) - [Remove the code first, then the flag](#remove-the-code-first-then-the-flag) - [Make cleanup a process](#make-cleanup-a-process) Chapter 07 # Cleaning up – Feature Flags pocket guide Flags come in two kinds. Release flags and experiment flags are temporary: they exist to get a change out safely or to measure it, and once that's done they're debt. Operational flags are permanent on purpose: a kill switch for an expensive feature under load, a disaster recovery switch, or an entitlement that decides which plan gets a feature. Cleanup is for the first kind. A temporary flag you leave behind is a code path nobody tests anymore, and it can cost money too. The web SDK evaluates every active flag available to the browser on load, so a request can bill for a flag your code stopped checking months ago. ## Let the rollout state decide For a temporary flag, the rollout state tells you which code path to keep Fig. 1: | Flag | Rollout | Age | Evals/day | In code | Verdict | | --- | --- | --- | --- | --- | --- | | new-checkout | 100% | 4 mo | ~29,000 | 3 files | Remove | | beta-nav | 0% | 5 mo | ~1,200 | 1 file | Remove | | pro-exports | 40% | 2 mo | ~6,500 | 2 files | Ask first | Fig. 1 – The rollout state tells you which code path to keep. | Rollout state | Keep | Then | | --- | --- | --- | | 100%, with no property filters | The enabled path | Remove the checks, deploy, confirm nothing still checks it, and delete the flag | | 0% | The fallback | Remove the new code and the checks, deploy, confirm nothing still checks it, and delete the flag | | Below 100%, or 100% of a filtered group such as a beta cohort | Nothing yet | Ask the owner whether the rollout stalled, is still running, or is meant to stay targeted. A flag that stays targeted is permanent | | Permanent | The flag | Tag it `keep`, `ops`, or `kill-switch`, so cleanup skips it | PostHog calls a flag stale when nothing has checked it in 30 days, or when it has sat at 100% for 30 days with no property filters. A flag you turned off on purpose isn't stale. A kill switch sits at 100% for months by design, so it can look stale, which is what the tag is for. ## Remove the code first, then the flag Remove the checks from your code, deploy, and only then delete the flag. For a flag at 100%, the deploy keeps the enabled path, so nobody loses the feature. In the other order, every leftover check loses its answer and falls back to your default, and the feature vanishes for everyone. Before you delete, confirm nothing still checks the flag. A deleted flag returns `false` or `undefined`, so an old mobile app version or a tab left open flips to the off path. The `$feature_flag_called` events stopping is a signal, not proof: SDKs send the event for locally evaluated and bootstrapped flags too, but not for checks with event capture turned off, such as `send_event: false` in the browser or `sendFeatureFlagEvents: false` in Node, and not for a Node `getFeatureFlagPayload()` call. Search your code for the key, and wait for old app versions to age out. ## Make cleanup a process Most flag debt comes from flags nobody owns. When you create a flag, give it an owner, a name that says what it's for, and a note on whether it's temporary or permanent. The owner of a temporary flag also owns its removal. Then let a process do the remembering. A [scout](https://posthog.com/docs/self-driving/scouts.md) can check your flags every day and report the ones that are done. When the cleanup is an obvious code change, it marks the report actionable, and a coding agent opens a draft pull request for you to review. It leaves alone any flag whose key it can't find in your code, and any flag tagged `keep`, `ops`, or `kill-switch`, so nothing disappears that it can't trace. [Open the flag debt scout](https://posthog.com/docs/self-driving/pocket-guide/flag-debt.md)A scout that checks your flags every day and reports the ones ready to remove. See also: [Cleaning up stale flags](https://posthog.com/docs/feature-flags/cleaning-up-stale-flags.md) · [Flag debt](https://posthog.com/docs/self-driving/pocket-guide/flag-debt.md) · [How GitHub and GitLab ship behind flags](https://posthog.com/product-engineers/github-gitlab-feature-flags.md)