Feature flags decouple deploy from release. You ship code dark and turn it on for 1% of users, then 10%, then 100%. Or you turn it off without a deploy when something breaks. By 2026 it’s a standard practice; this post is the working stack.
What flags buy you
- Decouple deploy from release. Deploy whenever; release when ready.
- Kill switch for incidents. Turn off broken features without a hotfix deploy.
- Targeted rollouts. Beta users first; enterprise customers later.
- A/B testing. Compare variants on real traffic.
- Migration ramp. Old code path → new code path with measurable cutover.
A team that ships without flags is rolling dice on every deploy.
OpenFeature — the standard
OpenFeature (CNCF graduated) standardizes the SDK shape. Your code:
from openfeature import OpenFeatureClient
client = OpenFeatureClient()
if client.get_boolean_value("new-checkout-flow", default=False, context={"user_id": uid}):
return new_checkout()
return old_checkout()
…works with any provider (LaunchDarkly, Flagsmith, custom) by changing the provider, not the code. Use it.
The contenders
| Type | Strengths | Free tier | |
|---|---|---|---|
| LaunchDarkly | SaaS | Mature, polished, expensive | Limited |
| Flagsmith | OSS or SaaS | Self-hostable | Generous |
| Unleash | OSS or SaaS | Solid, OpenFeature-native | Generous |
| PostHog Feature Flags | OSS or SaaS | Bundled with analytics | Generous |
| Custom (Postgres) | DIY | Free, full control | n/a |
For most 2026 teams: start with PostHog or Flagsmith (free, hosted, OpenFeature-compatible). Migrate to LaunchDarkly only if you need its enterprise features and can justify the cost.
Flag types
Boolean
new-feature: on/off. The default.
Percentage rollout
new-feature: 10% of users. Common for safe rollouts.
Targeted
new-feature: enabled for users in (org_id IN ...). Enterprise rollouts.
Variant
checkout-flow: A | B | C. A/B/C testing.
Patterns that work
1. Default off
New flags default to off. You explicitly turn them on. Reduces “oops, that wasn’t supposed to ship.”
2. Server-side flags for decisions; client-side for UI
Pricing logic, security checks, billing — server-side. Show/hide a banner — client-side. Don’t let clients lie about their flag values.
3. Cleanup discipline
Flags accumulate. A 3-year-old flag with both branches still in code is technical debt. Schedule monthly flag-cleanup tasks.
4. Default safe
If the flag service is down, the default is the safe value (usually current behavior).
5. Logging flag values in traces
Add flag values to OpenTelemetry spans. When debugging “why did this user see X?”, you can see which flag was active.
See OpenTelemetry End-to-End in 2026 .
Progressive delivery
Combine flags with deploy automation:
- Deploy new code, flag off.
- Turn on for internal team.
- Enable for 1% of users.
- Watch SLOs (see SLOs and Error Budgets ).
- Ramp to 10%, 50%, 100% over hours/days.
- Remove the old code path.
- Remove the flag.
Stop and roll back at any step if metrics degrade. Tools like Argo Rollouts (with Argo CD; see GitOps with Argo CD ) automate the SLO-watching part.
Cost of doing it wrong
- No flag system. Every deploy is high-stakes. Outages from bad releases are unrecoverable without a revert.
- Flags but no kill switches. Production breaks; you can’t turn off the bug without a deploy.
- Flags but no cleanup. Code grows; both branches remain; nobody knows which is “current.”
- Client-side flags for security. Attacker flips the flag; bypasses the gate.
- Flag service is single point of failure. Plan for graceful degrade if the flag service is down.
Read this next
- GitOps with Argo CD and Flux Explained
- SLOs and Error Budgets for App Developers
- OpenTelemetry End-to-End in 2026
- Platform Engineering and IDPs
If you want a small Postgres-backed flag service + OpenFeature provider, it’s at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .