Feature Flags and Progressive Delivery: Ship Safer, Faster
Feature flags decouple deploy from release, so shipping stops being a high-stakes event. Here is how to use them for progressive delivery without drowning in flag debt.
- Feature flags decouple deployment from release: code ships to production dark, then you turn a feature on for a chosen audience with a config change rather than a deploy.
- Progressive delivery builds on that by rolling a feature out gradually, from internal users to a small percentage to everyone, while you watch metrics and keep an instant kill switch ready.
- Name your flags by type: only release and experiment flags are meant to be temporary, so give each one an owner and an expiry from the start.
- The real risk is flag debt. Flags are cheap to add and easy to forget, so make removing a fully rolled-out flag part of the definition of done.
Feature flags are conditional switches in your code that let you turn a feature on or off with a configuration change instead of a deploy, and progressive delivery is the practice of using them to release that feature to a widening audience while you watch the system for trouble. Together they break the false coupling between deploying code and releasing a feature. You deploy continuously and calmly, then decide separately, and reversibly, who gets to see what. If a rollout goes wrong you flip the flag off and every user is back on the known-good path in seconds, no redeploy required. This works best on top of a healthy pipeline, and our guide to CI/CD pipeline best practices covers the foundation it all sits on.
Deploy Is Not Release
The single idea that makes all of this click is that deploying code and releasing a feature are two different events. A deploy puts code onto servers. A release exposes behavior to users. Traditionally they happen together, which is why deploys feel risky. A feature flag splits them apart.
With flags, code for a new feature can sit in production for days, merged and deployed but switched off. When you are ready, you flip the flag for a chosen audience, and if anything looks wrong you flip it back in seconds without touching the pipeline. Deploy becomes routine and boring, which is exactly what you want it to be, while release becomes a controlled, reversible decision.
The Types of Feature Flags
Flags are not all the same, and conflating them is how teams end up in a mess. Each category has a different purpose, lifespan and owner, so labelling them by type from the start keeps cleanup honest later.
| Flag Type | Purpose | Typical Lifespan | Owner |
|---|---|---|---|
| Release | Hide in-progress work and control a rollout | Short-lived, remove once fully on | Feature team |
| Experiment | Split traffic for an A/B test | Lives as long as the experiment | Product or data |
| Operational | Kill switches and circuit breakers | Often long-lived by design | Platform or SRE |
| Permission | Gate features by plan, role or customer | Effectively permanent | Product |
Only release and experiment flags are meant to be temporary. Mixing a permanent entitlement flag and a throwaway release flag in the same mental bucket is how cleanup stalls.
Progressive Delivery Patterns
A canary release with feature flags is a common starting point: expose the change to one forgiving cohort, watch error rates and latency, and only widen the audience when the numbers hold. Instant rollback is not really a separate pattern so much as the property that makes all the others safe.
| Pattern | How It Works | Best For | Blast Radius |
|---|---|---|---|
| Dogfooding | Turn it on for your own team first | Catching obvious breakage early | Internal only |
| Percentage rollout | 1 percent, then 5, 25, then everyone | Broad features with good metrics | Grows step by step |
| Canary by cohort | Target one low-risk segment or region | High-risk changes needing a contained test | One cohort |
| Ring-based rollout | Move through rings from most to least tolerant | Large user bases and staged confidence | Widens per ring |
| Instant rollback | Flip the flag off on bad metrics | Every rollout, as a safety net | Back to known-good |
Want to Ship With Less Fear?
We help teams put feature flags and progressive delivery in place so deploys become routine and releases become reversible. Tell us how you ship today and we will map a practical path to safer, faster delivery.
Feature Flags and Trunk-Based Development
Feature flags and trunk-based development are natural partners because both aim to keep integration continuous and branches short. When everyone merges to a shared main branch frequently, you avoid the pain of long-lived branches, but you need a way to merge unfinished work without exposing it. Flags are that way.
- Small, frequent merges: developers integrate to trunk daily, keeping branches short and merge conflicts rare.
- Incomplete work stays hidden: a half-built feature is merged behind an off flag, so it ships to production without being visible.
- Continuous integration stays honest: because everyone works against the same trunk, integration problems surface early instead of at a big merge.
- Release on your schedule, not the branch's: the feature goes live when the flag flips, decoupled entirely from when the code landed.
How to Roll Out a Feature Safely
A safe rollout is a repeatable sequence, not a leap of faith. The checklist below is the path we follow when releasing a non-trivial feature behind a flag, and it works whether you are on a managed flag platform or a simple config-driven toggle.
- Create the flag with a clear name, an owner and an expiry date, defaulting to off.
- Merge the feature behind the off flag so the code ships to production dark.
- Turn the flag on for your own team and internal users, and fix the obvious breakage.
- Expose it to a small cohort or a low single-digit percentage of real users.
- Watch error rates, latency and the key business metric before widening the audience.
- Step the rollout up in stages, pausing at each level to confirm the metrics hold.
- If anything moves the wrong way, flip the flag off and investigate on the known-good path.
- Once the feature is fully live and stable, remove the flag and its dead branch of code.
The last step is the one teams skip, and it is the one that matters most. A rollout is not finished until the temporary flag is gone.
Managing Flag Debt and What Drives the Cost
Every flag is a branch in your code and a line in your config. Add enough of them without cleaning up, and you get combinatorial complexity that nobody can reason about, plus the genuine risk of a stale flag being flipped by accident. This is the failure mode that turns flags from an asset into a liability. The effort a flag setup takes is less about licensing and more about the qualitative factors below.
- Give every temporary flag an owner and an expiry date at creation time, so removal is somebody's job, not nobody's.
- Track flags in one place, a register or a flag platform, so you can see what exists, who owns it and how old it is.
- Default to safety: a flag whose backing service is unreachable should fall back to the safe, known state, never to an undefined one.
- Keep the logic thin: a flag should choose between two clear paths, not accumulate nested conditions that become impossible to test.
Common Mistakes Teams Make With Feature Flags
Most feature flag pain comes from a handful of avoidable habits rather than the tool itself. These are the patterns we see most often when a flag setup starts to hurt instead of help.
- Never removing flags, so a short-lived release flag outlives its feature by a year and becomes a hidden hazard.
- Treating all flags the same, mixing permanent entitlements with throwaway toggles so cleanup never gets prioritised.
- Nesting flag logic until a feature depends on three toggles in combination that nobody can safely reason about or test.
- Rolling out to everyone at once anyway, which throws away the whole point of progressive delivery.
- Failing open to an undefined state when the flag service is unreachable, instead of falling back to the known-good path.
- Flagging tiny, low-risk changes by reflex, adding ceremony and cleanup overhead where none was needed.
Flags are cheap to add and expensive to leave lying around, so the removal step deserves as much discipline as the rollout itself.
How Flags Relate to Deployment Strategies
Feature flags sit at the application layer, while deployment strategies like blue-green and canary sit at the infrastructure layer, and the two complement each other. A canary deployment shifts a slice of traffic to a new version of the whole service, whereas a feature flag toggles one feature for one audience regardless of which version they hit. You often want both: infrastructure-level rollout to derisk the deploy, and flag-level control to derisk the feature. Our comparison of blue-green vs canary deployment explains the infrastructure side, and our overview of Kubernetes deployment strategies shows how these rollouts are orchestrated in a cluster.
This is also where flags can be overkill. A copy fix or a trivial patch rarely needs a flag and its cleanup overhead. A very small team that can revert and redeploy in minutes may find a full flag platform heavier than the problem warrants. And truly one-way changes, such as some irreversible database migrations, cannot be undone by flipping a boolean, so a flag there gives a false sense of safety. Match the ceremony to the risk. When teams engage us, we typically start by mapping how they ship today and introducing flags only where they earn their keep, so the discipline is built in from the first rollout.
Conclusion
Feature flags and progressive delivery change the emotional temperature of shipping. Deploy becomes a routine, low-stakes act, and release becomes a controlled, reversible decision you make while watching real metrics. The payoff is real: faster iteration, smaller blast radius, and an instant kill switch when something goes wrong. The discipline is equally real, because flags left to rot become a hazard of their own, so treat release flags as temporary, give each one an owner and an expiry, and remove it when its job is done. Used with that discipline, flags let a team ship both safer and faster at the same time, which usually feels like a trade-off but does not have to be. If you want help putting this into practice, contact us and we will map it to how your team already works.
Frequently asked questions
What are feature flags and how do they enable progressive delivery?
Feature flags are conditional switches in your code that decide whether a feature is active for a given user, controlled by configuration rather than a deploy. They enable progressive delivery by letting you ship code to production in an off state and then release it gradually, to internal users, then a small percentage, then everyone, while you watch metrics. Because a flag can be flipped off instantly, any rollout comes with a built-in kill switch that needs no redeploy. This separation of deploy from release is what makes graduated, reversible rollouts possible.
What is the difference between a feature flag and a canary deployment?
A canary deployment works at the infrastructure level by routing a small slice of traffic to a new version of the whole service, while a feature flag works at the application level by toggling one specific feature for a chosen audience. Canary derisks the act of deploying new code, whereas a flag derisks exposing a particular behavior to users. They are complementary rather than competing, and mature teams often use both together. The canary protects the deploy, and the flag gives fine-grained control over the release.
How do feature flags support trunk-based development?
Trunk-based development relies on frequent merges to a shared main branch, which raises the problem of integrating unfinished work without exposing it. Feature flags solve this by letting developers merge incomplete features behind an off flag, so the code ships to production while staying invisible to users. This keeps branches short, makes merge conflicts rare, and surfaces integration issues early. The feature then goes live when the flag is flipped, completely decoupled from when the code was merged.
How do I avoid feature flag debt?
Feature flag debt builds up when temporary flags are added and never removed, cluttering the code and creating stale toggles that can be flipped by mistake. Avoid it by giving every temporary flag an owner and an expiry date when you create it, and by tracking all flags in one register or platform. Make removing a fully rolled-out flag part of the definition of done for the feature rather than a someday task. Distinguishing temporary release flags from permanent entitlement flags also keeps cleanup focused on the ones that are meant to disappear.
What is the safest way to roll out a feature behind a flag?
Start by shipping the code to production behind an off flag so nothing is exposed. Turn the flag on for your own team first, then a small cohort or low percentage of real users, and watch error rates, latency and the key business metric at each step. Widen the audience in stages only while the metrics hold, and flip the flag off immediately if anything moves the wrong way. Once the feature is fully live and stable, remove the flag so it cannot cause trouble later.
When should I not use a feature flag?
Flags add value when a change carries real risk or benefits from a gradual rollout, but they are overkill for tiny, low-risk edits like a copy fix or a trivial patch. Very small teams that can revert and redeploy in minutes may find a full flag platform heavier than the problem warrants. Flags also give a false sense of safety for truly one-way operations, such as some irreversible database migrations, where flipping a boolean cannot actually undo the change. Match the ceremony to the risk rather than flagging everything by reflex.
