Feature Flags (also known as Feature Toggles) separate the idea of deployment from the idea of release.

Core Concept

Deploy code to production with new features hidden behind toggles, then enable features independently of deployment.

Benefits

Decouple Deployment from Release

  • Deploy incomplete features safely to production
  • Enable features for specific users or segments
  • Perform gradual rollouts and A/B testing
  • Quick rollback without redeployment

Risk Reduction

  • Test in production with real traffic
  • Canary releases to small user groups
  • Kill switches for problematic features
  • Safer continuous deployment

Business Flexibility

  • Enable features on schedule independent of development
  • Different features for different customer tiers
  • Regional or market-specific capabilities

Types of Feature Flags

Release Toggles

Short-lived flags for incomplete features in progress.

if (featureFlags.IsEnabled("new-checkout-flow"))
{
    return new EnhancedCheckoutService();
}
return new LegacyCheckoutService();

Experiment Toggles

A/B testing and experimentation flags.

Ops Toggles

Circuit breakers and system behavior controls.

Permission Toggles

Enable features based on user permissions or plan tiers.

Managing Feature Flag Debt

Flag Lifecycle

  1. Create: New feature under development
  2. Test: Enable for internal users/testers
  3. Roll out: Gradual increase in exposure
  4. Complete: 100% enabled
  5. Remove: Clean up flag and old code path

Technical Debt

  • Old flags accumulate as technical debt
  • Document flag purpose and removal plan
  • Set expiration dates
  • Regular cleanup of completed flags

Implementation Patterns

Simple Boolean Flags

public class FeatureFlags
{
    private readonly IConfiguration _config;
 
    public bool IsEnabled(string featureName)
    {
        return _config.GetValue<bool>($"Features:{featureName}");
    }
}

User-Specific Flags

public class FeatureFlags
{
    public bool IsEnabledForUser(string featureName, User user)
    {
        // Check user properties, beta groups, etc.
        if (user.BetaFeatures.Contains(featureName))
            return true;
 
        return _globalFlags.IsEnabled(featureName);
    }
}

Percentage Rollouts

public class FeatureFlags
{
    public bool IsEnabledForUser(string featureName, User user)
    {
        var rolloutPercentage = _config.GetValue<int>($"Features:{featureName}:Rollout");
        var userHash = GetConsistentHash(user.Id, featureName);
 
        return userHash % 100 < rolloutPercentage;
    }
}

Tools and Services

  • LaunchDarkly
  • Split.io
  • Unleash
  • AWS AppConfig
  • Azure App Configuration
  • Feature flags in Git Forge platforms (GitHub, GitLab)

Resources