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
- Create: New feature under development
- Test: Enable for internal users/testers
- Roll out: Gradual increase in exposure
- Complete: 100% enabled
- 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
Related Concepts
- Organizational Practices - Broader team practices
- Technical Debt - Managing flag cleanup
- Good Software Practices