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

TypeStrengthsFree tier
LaunchDarklySaaSMature, polished, expensiveLimited
FlagsmithOSS or SaaSSelf-hostableGenerous
UnleashOSS or SaaSSolid, OpenFeature-nativeGenerous
PostHog Feature FlagsOSS or SaaSBundled with analyticsGenerous
Custom (Postgres)DIYFree, full controln/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:

  1. Deploy new code, flag off.
  2. Turn on for internal team.
  3. Enable for 1% of users.
  4. Watch SLOs (see SLOs and Error Budgets ).
  5. Ramp to 10%, 50%, 100% over hours/days.
  6. Remove the old code path.
  7. 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

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 .