How to use feature flags to reduce deployment risk in Python services without creating permanent configuration debt or inconsistent behaviour.
Give every flag an owner, a safe default, a rollout rule and an expiry date before it enters the service.
Use flags for a specific risk
A flag is useful when it enables gradual exposure, a reversible kill switch or an experiment with a measurable outcome. It is not a substitute for an unfinished design or a place to keep two permanent implementations.
Describe the audience, default state and failure mode. If the flag provider is unavailable, the service must know whether to preserve the safe old behaviour or stop an unsafe operation.
Keep evaluation consistent
A request should not see one flag decision in the API layer and another in a background worker because a remote value changed midway through work. Evaluate at an explicit boundary and carry the relevant decision with the command when consistency matters.
Flag targeting can become an authorisation concern. Do not expose sensitive targeting rules to clients, and avoid using uncontrolled user input as the basis for privileged behaviour.
Remove flags as part of delivery
After a rollout succeeds, delete the inactive path, tests and configuration. Old flags multiply combinations and make an incident harder to diagnose because engineers no longer know which code is live.
Track exposure, error rate and business outcome during the rollout. A flag that is permanently enabled without evidence should become ordinary code or be retired deliberately.
Evidence to take into review
- The flag has an owner, purpose and expiry date.
- Default and provider-failure behaviour are safe.
- Evaluation is consistent across a workflow.
- Exposure and errors are measured during rollout.
- Inactive branches are removed after the decision.
Explore all engineering notes.
Use PRODUCTION-7 to connect this concern with the other dimensions of a trustworthy backend.
View all articles Get the checklist