KyoMel / Yogyakarta, Indonesia

Term 244244 / 344

Feature Flag Debt

Month
May 2026
Day
28
Source
2026/may-term.md

Definition:

Feature flag debt is the accumulation of old, forgotten feature flags (also called “feature toggles”) that were used to gradually roll out or test a feature, but were never cleaned up after the feature shipped. These leftover flags clutter the codebase, making code harder to understand, test, and maintain.

Think of it like scaffolding left on a building after construction is done. It served a purpose during the build, but now it’s ugly, blocks the view, and is a safety hazard waiting to happen.

How It Happens

  Dev adds a flag: if (newCheckoutFlow) { ... }
        │
        ▼
  Feature ships, 100% ON for 6 months
        │
        ▼
  Nobody removes the old code path
        │
        ▼
  A year later: 2 branches, 4x tests, no one remembers which is "real"
        ▼
  💸 That's flag debt.

Example:

Suppose your team builds a new dark-mode UI behind a feature flag:

// Clean at first — two clear paths
function renderPage() {
  if (featureFlags.isEnabled("dark-mode-v2")) {
    return renderDarkMode();
  } else {
    return renderLegacyLightMode();   // ← old version still here
  }
}
Dark mode launches. Everyone loves it. The flag is set to 100% ON permanently.

Now imagine this happens six more times — new search bar, new checkout, new nav. Each time, the old code path stays. A year later:

function renderPage() {
  if (featureFlags.isEnabled("dark-mode-v2")) {
    if (featureFlags.isEnabled("search-v3")) {
      if (featureFlags.isEnabled("checkout-redesign")) {
        if (featureFlags.isEnabled("new-nav-bar")) {
          return renderNewExperience();  // ← only this path actually runs in production
        } else { return renderOldNav(); }    // dead code
      } else { return renderOldCheckout(); } // dead code
    } else { return renderOldSearch(); }     // dead code
  } else { return renderLegacyLightMode(); } // dead code
  // ↑ 4 dead branches, 5x the test matrix, zero value
}
The Real Cost
Cost	Impact
Code complexity	Every flag doubles the number of paths to understand and test
Slower development	New devs waste time reasoning about dead paths
Bugs in dead code	Someone accidentally changes the legacy path → breaks nothing in production, but wastes time
Painful cleanup	The longer flags live, the more entangled they become — removal becomes risky

Keep reading