Meet Unleash at one of the events we're attending this year➩ See where we'll be

Watch "Implementing a Kill Switch for AI"

Events

Join the Unleash team to learn how to integrate runtime control in your AI strategy.

How should I implement a kill switch for a critical production feature?

Alex Casalboni

Alex Casalboni

Developer Advocate

August 13, 2026

A kill switch is a feature flag whose only job is to turn off a piece of production behavior without a deploy. To implement one well, wrap the risky code in an inverted flag so that “off” is the safe default, decide in advance what your application does when the switch is thrown, and make sure the switch keeps working even when the rest of your system does not. Everything after that is process: who can flip it, how fast they can do it, and how you know it still works when you need it.

What a kill switch does that a rollback does not

Kill switches are one of the standard feature flag types, alongside release, experiment, operational, and permission flags. They exist because redeploying is a slow way to stop the bleeding. A rolling deployment replaces one version of your service with another across a fleet of servers, which takes minutes at best and longer if you have a large fleet or a database migration in the middle of it. A kill switch turns off one feature while everything else keeps running.

That precision matters during an incident. If a new recommendation engine is timing out and dragging your product pages down with it, you can disable that one thing and leave the twelve other changes from the same release in place.

Unleash treats kill switches as a first-class flag type, and you set it when you create the flag. The type does not change how the flag evaluates, but it tells everyone reading the flag list what the flag is for and stops someone from cleaning it up six months later on the assumption it was a leftover release flag.

Make “off” the safe state

The single most useful convention for kill switches is to invert the logic. Unleash’s guidance is to wrap the flaky feature in an inverted flag: your application assumes the feature is working as long as the flag stays disabled, and enabling the flag is what turns the feature off.

The naming carries real weight here. If your flag is called new-recommendations-enabled and has to be true for the feature to work, then a failure to reach the flag service, a bad cache, or a misconfigured default all point the same direction: the feature goes dark unexpectedly. Call it disable-recommendations, default it to false, and the flag does something only when a human deliberately turns it on.

Write the name so anyone reading a Slack alert at 2am understands what happens when they flip it. disable-checkout-v2 beats checkout-flag-3.

Decide what the system does when you throw the switch

The goal is graceful degradation: the system loses a capability and keeps serving users. A switch that leaves people staring at a 500 error has only made the failure arrive sooner.

Work out the fallback path when you write the flag, while you still have time to think it through. Some common patterns:

  • Fall back to the previous implementation. The old code path stays in the binary behind the flag. This is why many teams keep the old checkout or the old search backend compiled in for a full release cycle after the new one ships.
  • Fall back to a static or cached response. A personalization service that is down can serve a generic set of results rather than an empty page.
  • Fall back to hiding the feature. For additive features like a new dashboard widget, the fallback is simply not rendering it.
  • Fall back to a queue. For write paths, accept the request, park it, and process it once the feature is back on. This works only if the operation tolerates delay.

For most flags, a plain if/else is the right way to express this in code. Unleash’s guidance on managing flags in your codebase notes that the strategy pattern adds overhead rarely worth paying for short-lived flags, though it fits a long-lived kill switch on a core component reasonably well. Reach for it when the feature has two genuinely different implementations you expect to swap between for a while.

Make sure the switch works when your systems are struggling

Kill switches get used during incidents, which is exactly when parts of your setup are unreliable. Unleash’s best practices guide is direct about the requirement: if the flag system fails, your application should keep running.

Unleash handles this by having backend SDKs evaluate flags locally. The SDK fetches flag configuration into an in-memory repository and refreshes it on a schedule, so evaluation is a local lookup rather than a network call. If Unleash becomes unreachable, the SDK keeps serving the last known configuration. A few things to confirm on your side:

  • Set sensible default values in the SDK so a cold start with no network still produces safe behavior.
  • Bootstrap flag configuration from a local file or object store so a restart during an outage does not leave you with empty defaults.
  • Check your refresh interval. A 15-second poll means the switch takes up to 15 seconds to reach every instance. That is usually fine. If you need faster, tighten it or run Unleash Edge closer to your services (streaming).

Balance speed of response against accidental flips

These two requirements pull against each other. You want an on-call engineer to throw the switch in seconds. You also do not want someone flipping a production kill switch while poking around the admin UI.

Change requests give you an approval step before flag changes land in a protected environment, similar to a pull request review. That is the right control for most production flag changes. Kill switches deserve a separate decision: many teams exempt them from change request review, or grant a small on-call role the ability to bypass it, on the grounds that a two-person approval requirement is the wrong thing to hit during an outage.

Whatever you choose, pair it with scoped permissions and a clean project and environment setup so the people who can flip production switches are the people who should be able to, and every change lands in the event log with a name attached. You can drive all of this through the Unleash API, which is worth wiring up if you want a monitoring alert to trip the switch automatically, or a runbook command that does it without opening a browser.

Test the switch before you need it

An untested kill switch is a guess. Flip it in staging as part of the feature’s normal testing, then flip it in production during a low-traffic window and watch what happens. Confirm the fallback path renders, error rates stay flat, and turning the switch back off restores the feature cleanly. Repeat this on a schedule, because the fallback code path rots the same way any unexercised code does.

Plan for the flag’s long life

Most feature flags should be short-lived. Kill switches are one of the documented exceptions, along with internal debugging flags. That permanence creates its own maintenance work.

Give every kill switch a named owner and a review date. Tag it so it does not get swept up in cleanup passes. Resist the temptation to build one parent flag that acts as a global kill switch for a group of child flags: Unleash’s guidance on using flags at scale points out that parent and child targeting rules interact in ways that are easy to misconfigure.

Finally, watch for kill switches that have outlived their purpose. Unleash’s technical debt view surfaces stale and potentially stale flags, including kill switches you have never enabled in production. A switch protecting a code path you deleted two quarters ago is just a conditional nobody reads. Archive it and take the branch out of your code.

The short version

Invert the logic so off is safe. Write the fallback before you write the flag. Confirm the switch still works when Unleash is unreachable. Decide who can flip it and how fast. Test it on a schedule. Give it an owner, and retire it when the risk it covers is gone.