← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Feature Flag / Feature Toggle

quality PHP 5.0+ Beginner
debt(d9/e7/b7/t5)
d9 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'silent in production until users hit it' (d9). The detection_hints specify automated=no and tools are feature-flag management platforms (Unleash, LaunchDarkly, Flagsmith) that help manage flags but do not automatically detect misuse patterns like flag debt accumulation, nested flag conditions, or missing cleanup. The code_pattern describes 'new feature deployed to all users at once with no gradual rollout or kill switch' — this is invisible at compile time, lint time, and even in testing; it only manifests as a missing safety mechanism in production. Flag accumulation and dead-code conditions are silent until someone is tracing a production bug.

e7 Effort Remediation debt — work required to fix once spotted

Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix describes the happy-path of wrapping a feature and decommissioning old code, but the common_mistakes enumerate the real remediation cost: cleaning up accumulated flag debt means locating every flag check across the codebase, removing the conditional branches, deleting the old code paths, and updating tests — a cross-cutting operation. Nested flag conditions that create combinatorial test space make this significantly harder than a localised fix.

b7 Burden Structural debt — long-term weight of choosing wrong

Closest to 'strong gravitational pull' (b7). Feature flags apply across web, api, and cli contexts and are tagged as deployment/devops/continuous-delivery patterns, meaning they affect every deployment pipeline and release decision. The common_mistakes highlight that unremoved flags become permanent dead code conditions that shape every future change to the affected code paths. Flag debt accumulates across the whole codebase over time, imposing a persistent productivity tax on all work streams touching flagged areas.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap — a documented gotcha most devs eventually learn' (t5). The misconception field explicitly states that developers believe flags are only for hiding incomplete features, missing the broader uses (A/B testing, canary releases, kill switches). The common_mistakes reinforce the cleanup trap: most developers deploy flags without planning removal, leading to flag debt. These are documented, well-known gotchas that most teams encounter and learn — serious enough to cause real pain but not contradicting an analogous concept in a catastrophic way.

About DEBT scoring →

Also Known As

feature toggle feature switch feature flipper

TL;DR

A runtime switch that enables or disables features without deploying new code, decoupling deployment from release.

Explanation

Feature flags (toggles) wrap new code in conditional blocks controlled by configuration, environment variables, or a remote flag service. They enable: trunk-based development (merge incomplete code safely), canary releases (enable for a percentage of users), A/B testing, kill switches for problematic features, and operational flags for performance tuning. The cost is codebase complexity — old flags must be cleaned up once permanently enabled/disabled. Organise flags by type (release, ops, experiment, permission) and define explicit removal criteria.

Common Misconception

Feature flags are only for hiding incomplete features. They also enable A/B testing, canary releases, kill switches for faulty functionality, and gradual rollouts — and they accumulate as tech debt if not removed after the feature is fully deployed.

Why It Matters

Feature flags decouple deployment from release — code ships dark, then features are enabled per user or percentage without a new deployment, enabling safe rollout and instant rollback.

Common Mistakes

  • Not cleaning up flags after the feature is fully released — flag debt accumulates and the conditions become permanent dead code.
  • Using feature flags for configuration or environment differences — that is what environment variables are for.
  • Nested feature flags that create combinatorial conditions impossible to test exhaustively.
  • Not logging or monitoring flag state — when something breaks you can't tell which flag combination caused it.

Avoid When

  • Flags are never removed — accumulated dead flags become permanent complexity and technical debt.
  • The flag controls security-critical behaviour — a misconfigured flag disabling auth is catastrophic.
  • Flags are used as permanent configuration instead of short-lived release toggles.
  • Too many flags interact — combinatorial testing of N flags requires 2^N test cases.

When To Use

  • Trunk-based development where incomplete features must be merged to main without being user-visible.
  • Canary releases and A/B tests where the new behaviour is shown to a percentage of users.
  • Kill switches for risky features that may need to be disabled instantly in production.
  • Per-tenant or per-customer feature enablement in SaaS applications.

Code Examples

✗ Vulnerable
// Nested flags create untestable combinations:
if (featureEnabled('new_checkout')) {
    if (featureEnabled('new_payment')) {
        if (featureEnabled('new_tax_engine')) {
            // 8 combinations to test — combinatorial explosion
        }
    }
}
✓ Fixed
class FeatureFlags {
    public function isEnabled(string \$flag, ?User \$user = null): bool {
        \$feature = Feature::where('key', \$flag)->first();
        if (!\$feature || !\$feature->enabled) return false;

        // Percentage rollout — hash user ID into 0-99 bucket
        if (\$user && \$feature->rollout_percent < 100) {
            \$bucket = crc32(\$flag . \$user->id) % 100;
            return \$bucket < \$feature->rollout_percent;
        }
        return true;
    }
}

if (\$flags->isEnabled('new_checkout', \$user)) {
    return \$this->newCheckout->process(\$cart);
}
return \$this->legacyCheckout->process(\$cart);

Added 15 Mar 2026
Edited 25 Mar 2026
Views 39
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 3 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 2 pings S 0 pings S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 2 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F
No pings yet today
No pings yesterday
Amazonbot 10 Perplexity 9 Ahrefs 4 SEMrush 3 Unknown AI 2 Majestic 1 Google 1
crawler 29 crawler_json 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Wrap new features in a flag check (if ($flags->isEnabled('new-checkout', $user))): deploy with the flag off, enable for 5% of users, then 100% — decommission old code after full rollout
📦 Applies To
PHP 5.0+ web api cli
🔗 Prerequisites
🔍 Detection Hints
New feature deployed to all users at once with no gradual rollout or kill switch
Auto-detectable: ✗ No unleash launchdarkly flagsmith
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: Medium ✗ Manual fix Fix: Medium Context: File Tests: Update

✓ schema.org compliant