Deploy on Friday. Release on Monday. That’s the power of feature flags.
The traditional model couples deployment with release—code goes to production, users see it immediately. Feature flags break that coupling, letting you deploy dark code and control visibility separately from deployment.
The Core Pattern
A feature flag is a conditional that wraps functionality:
| |
Simple in concept. Transformative in practice.
Why This Matters
1. Deployment becomes low-risk
Your CI/CD pipeline can deploy to production multiple times per day. New features ship behind flags, invisible to users. If something breaks, you haven’t exposed anyone to it.
2. Instant rollback without rollback
Production incident? Toggle the flag off. No redeployment, no rollback procedures, no waiting for CI. The old code is still there—you just show it again.
3. Progressive rollout
Instead of all-or-nothing releases:
- Enable for internal users first
- Expand to 1% of traffic
- Watch metrics, expand to 10%
- Full rollout when confident
4. A/B testing built-in
Feature flags are the foundation for experimentation. Route users to variants, measure outcomes, make data-driven decisions.
Implementation Approaches
Simple: Environment Variables
Good enough for small teams:
| |
Pros: No dependencies, no latency, no cost. Cons: Requires redeployment to change. No targeting. No gradual rollout.
Better: Configuration Service
Store flags in a database or config service:
| |
Pros: Runtime changes without deployment. Targeting capability. Cons: Latency (mitigate with caching). Need to build and maintain.
Production-Grade: Dedicated Platform
LaunchDarkly, Split, Flagsmith, Unleash—purpose-built platforms handle:
- Edge-cached evaluation (millisecond latency)
- Sophisticated targeting rules
- Audit logs
- Scheduled rollouts
- Kill switches
Worth the cost for high-stakes deployments.
Targeting Strategies
Flags become powerful with targeting rules:
| |
Common targeting dimensions:
- User attributes (plan, tenure, role)
- Geographic (country, region)
- Technical (browser, platform, app version)
- Random percentage (canary releases)
- Time-based (scheduled launches)
The Progressive Delivery Pipeline
Combine flags with observability for safe releases:
Automate the expand/rollback decision:
| |
Flag Hygiene
Flags accumulate. Old flags become technical debt—dead code paths, confusing conditionals, test complexity.
Practices that help:
- Expiration dates: Every flag gets a removal deadline when created
- Ownership: Assign an owner responsible for cleanup
- Automated detection: Lint rules that flag old flags
- Regular audits: Monthly review of active flags
| |
Anti-Patterns
Flag spaghetti: Nesting flags inside flags, creating combinatorial complexity. If you need if (flagA && !flagB || flagC), refactor.
Permanent flags: Some flags never get removed. They’re not feature flags—they’re configuration. Treat them differently.
Testing all combinations: With 10 binary flags, you have 1,024 possible states. Don’t test all combinations—test the paths that matter.
Flag-driven architecture: If your entire application flow depends on flag states, you’ve built a mess. Flags should wrap features, not define architecture.
The Mental Model
Think of feature flags as giving you a remote control for production:
- Play: Enable the feature
- Pause: Disable while you investigate
- Rewind: Roll back to old behavior
- Fast-forward: Skip the queue, enable for specific users
The code is already deployed. You’re just deciding who sees what, when.
That’s the power: deployment becomes a non-event. Release becomes a decision you can make, change, and reverse without touching your CI/CD pipeline.
Deploy on Friday. Watch the metrics over the weekend. Release on Monday. Sleep well.