When to use Feature Flags (and when not to)
This is the outcome from a discussion at work, which has been bothering me for some years.
This is designed to be a 5 minute read tops. Here’s the AI one-liner if you really want it:
Not everything is a feature flag. If the caller can choose, version your API. If engineering owns it, use config or env vars. Only reach for a flag platform when non-engineers need self-service toggling or you need toggle state correlated with analytics.
Please read the full page if you can.
Context
A discussion on whether backend feature flags are necessary, and when they’re actually the right tool. The conclusion: “feature flag” conflates three distinct patterns. Using the right one depends on who makes the decision and whether you need observability.
These principles apply regardless of discipline. Frontend, backend, mobile, infrastructure: the same three patterns hold.
The Three Patterns
1. Consumer Choice
The consumer (user, frontend, calling service) decides. No flag needed.
- Light/dark mode: user preference stored client-side
- FE calling /v1 or /v2 of an endpoint: FE decides which to call
- New payment provider: both endpoints exist, caller picks
- Webhook payload change: new version, consumers migrate at their pace
Rule: If someone downstream can choose, let them. Version your APIs. Accept both until old traffic stops, or communicate a deprecation date.
2. Operational Control via Config
Engineering owns it. Changed via deploys, Terraform, or parameter stores.
- Kill switches
- third-party dependencies
- dangerous/new processes
- pausing an expensive data migration
- Redis cache bypass toggle as an env var
- Tuneable dials
- Rate limits
- Throttle thresholds
- Timeout durations
- Batch processing limits
Rule: Binary on/off or tuneable values, owned by the team that runs the service. A PR or parameter store change is fine. No flag platform needed.
Note: Env vars typically require a redeploy or restart to take effect. Parameter stores (SSM, Secrets Manager) can be read at runtime without redeployment. Prefer a parameter store if you need sub-minute response to a change.
3. Dynamic Control and Observability via a Flag Platform
Toggled frequently or by non-engineers. State is tied to analytics.
- Maintenance page (product team toggles without a deploy)
- Promotional banners and seasonal content
- Gradual rollout of a cross-cutting change (10% → 100%)
- A/B tests on UI flows
Rule: Use a flag platform (Amplitude, Unleash etc.) when non-engineers need self-service toggling, changes are frequent or urgent, and you want the toggle state correlated with user metrics.
The Deciding Questions
| Question | If yes → |
|---|---|
| Can the caller choose? | Versioning (pattern 1) |
| Does engineering own it, and is a deploy acceptable? | Config (pattern 2) |
| Do non-engineers need to flip it, or do you need analytics on the toggle state? | Flag platform (pattern 3) |
Summary
Most backend work falls into patterns 1 or 2. Pattern 3 is common on the frontend but rare on the backend.
Calling everything a “feature flag” leads teams to reach for a flag platform when versioning or config would be simpler and more appropriate.
Final Thoughts
Patterns 2 and 3 will always require a cleanup lifecycle (expiry dates, removal tickets, periodic audits).