Product engineering
Feature Flags: Release Safely Without Permanent Debt
Feature flags expose changes gradually, measure impact, and allow quick rollback. Set owners, audiences, safe defaults, and removal dates before rollout.
TL;DR — Feature flags separate deploying code from exposing behavior. They let a team release a change to a small, chosen audience, observe it, and turn it off quickly. They are valuable when the flag has a clear purpose, owner, audience rule, and removal date. A flag without those becomes another untested code path.
A feature flag is a decision point in software: this customer gets the new behavior, another customer keeps the existing behavior. That makes a release less all-or-nothing. It does not make the underlying change safe by itself. Both paths must work, permissions must remain consistent, and the team must know who can change the flag and what evidence permits a wider rollout.
The OpenFeature specification provides a vendor-neutral model for evaluating flags, while LaunchDarkly’s feature flag guide illustrates common uses such as controlled releases and operational kill switches. The implementation tool matters less than the operating discipline around it.
Use the right type of flag
A release flag temporarily gates an incomplete or risky change. Its planned end state is deletion after the new path becomes standard. An operational flag is a kill switch for a dependency or expensive capability; it needs an on-call owner and a documented safe state. An experiment flag assigns audiences to alternatives and needs a metric and end decision. A permission flag controls an entitlement and requires stronger audit and authorization rules.
Do not use a flag to avoid deciding whether a feature should exist. A flag is appropriate when you know the intended destination but need safer exposure. If a team wants to support both behaviors indefinitely, that is product configuration and should be designed as such.
Make audience selection explicit
The first rollout group should be chosen for a reason: internal staff, a consented design partner, a percentage of eligible traffic, or a low-risk region. “Ten percent” alone is not a safety plan. Decide what makes a request eligible, whether the assignment is stable for a customer, and how to prevent a sensitive user from seeing an inappropriate path.
Hypothetically, a new checkout calculation is enabled for employees first, then for a small group of customers who opted into a pilot. The team compares successful checkout completion, calculation errors, and support reports against the old path. If errors cross its pre-agreed threshold, the operational owner disables the flag. This is a release decision, not an A/B-test benchmark; the thresholds follow the product’s own risk tolerance.
Run that path in a staging environment first, but remember that production flags must still tolerate real identity, permissions, caching, and dependency behavior. A load test may be needed when the enabled feature changes database or API work.
Guard against flag debt
Every flag increases combinations. Two independent boolean flags can produce four paths; five can produce 32. You do not need to test every theoretical combination when audience rules make some impossible, but you do need to record which combinations are supported. A stale release flag also obscures the normal behavior, confusing engineers and customers long after the launch.
Keep a registry with the flag key, purpose, type, owner, allowed audiences, creation date, intended removal date, and safe default. Alert on expired flags. Require deletion work in the same roadmap as the rollout; “we will clean it up later” is how temporary logic becomes architecture.
Failure modes to prevent
- The client hides a button while the server still permits the action, or the reverse.
- A cached response ignores flag context and serves one audience’s result to another.
- A percentage rollout changes assignment on each visit, making bugs impossible to reproduce.
- A kill switch still calls the expensive dependency before checking the flag.
- A flag is retired in code but continues to exist in configuration, inviting a false sense of control.
API versioning is related but distinct. A feature flag controls exposure; a versioned API manages an external contract. Do not tell an integration partner that a flag is their migration path.
Acceptance checklist
- The flag has a named type, owner, default, audience rule, and removal date.
- Both enabled and disabled paths have tests for authorization and critical outcomes.
- Rollout metrics and a rollback decision are written before exposure.
- The service evaluates the flag before costly or irreversible work.
- Cleanup is scheduled and verified after the rollout concludes.
Feature flags let a founder buy learning and reversibility. The price is disciplined ownership; pay it up front, and the flag stays a release tool instead of becoming permanent complexity.
Related paths