🛡 Guarded Release:
ship, watch, auto-roll-back

Roll a change out to a slice of live traffic, let LaunchDarkly watch a metric you care about, and if the new version regresses, it rolls itself back — automatically, in minutes, before most users ever notice.

🔵 LD Guarded rollouts 📉 Guarded by a metric ⏪ Automatic rollback

What a guarded release is

A normal flag flip is all-or-nothing: you turn a feature on and hope. A guarded release turns that hope into a safety net. You ship the new version to a percentage of users, keep the rest on the known-good version as a control, and point LaunchDarkly at a metric — error rate, latency, conversions.

LaunchDarkly compares the two groups in real time. If the new version is measurably worse, it reverts to the safe version on its own and tells you why. No pager, no war room, no scramble to remember how to undo the deploy.

The difference from a plain rollback: the software decides, using data, in the time it takes to read this sentence — and it only ever exposes the change to a fraction of people while it's unsure.

🛡
Deploy is not release

Code ships dark, then a guarded release decides — on evidence — whether it's safe to keep. A bad change is caught by the metric, not by a customer tweet.

📸
Screenshot placeholder: Monitoring tab
Flag → Monitoring: the guarded release with treatment/control arms, the guard metric, and "rolled back automatically" banner

A guarded release on the Monitoring tab, reverted after detecting a regression

Use cases

Who sleeps better because of it

A guarded release is a risk-reduction tool, so its value reads differently at every level of the org.

Persona What they care about How a guarded release delivers
👔 C-suite (CTO / CIO) Uptime, brand risk, the cost of a bad release reaching customers Bad changes are contained to a fraction of traffic and reverted automatically. "Move fast" stops being at odds with "don't break things" — you ship more and post higher availability.
📊 VP Eng / Directors Change-failure rate, MTTR, release throughput The mean-time-to-recovery for a guarded change is measured in minutes and requires no human. Teams release far more often because the downside is capped.
🚨 SRE / On-call Fewer 2am pages, faster mitigation, less toil The rollback happens before the alert would have fired. On-call reviews what LaunchDarkly already did instead of being woken to do it by hand.
💻 Developers Shipping without fear; reverting without a redeploy Merge, ship behind the flag, let the guard watch. If it's bad, it's off in minutes with no hotfix branch — the code is still deployed, just not served.
🧭 Product managers Getting features to users safely, protecting core funnels Ship the new checkout to 50% guarded by the booking-error rate. If it hurts conversions, it never reaches the other half — the funnel is protected automatically.

In this demo app

Every day at 7am ET, Toggle Travel "deploys" a new checkout that fails every payment. It ships as a guarded release to 50% of live traffic, guarded by the booking-error metric. Within minutes the treatment arm's errors spike, LaunchDarkly detects the regression against the healthy control arm, and reverts to the stable checkout automatically — while session replay captures real users hitting the failure. No human touches it.

📸
Screenshot placeholder: Auto-rollback event
Monitoring/flag history: "Default rule rolled back automatically after detecting a regression for Booking Errors"

The moment LaunchDarkly reverts the release on the booking-error regression

98%
production deploy success rate
Customer win story

Vodafone

With LaunchDarkly, Vodafone releases continuously — around 363 times a month, up from once a quarter — at a 98% production success rate, and can resolve incidents immediately by flipping the flag rather than rolling back a deploy. Even shipping a record volume of change, the company posted its highest availability of the year.

Read the case study →
Deep dive

How Toggle Travel uses it

Expand each topic for real configuration and code from this app, with the LD docs to go deeper.

🛡
How a guarded release works Treatment vs control, a metric, and an automatic decision
1
Start the rollout The new variation (treatment) is served to a slice of traffic; the rest stay on the current variation (control)
2
Monitor a guard metric LaunchDarkly watches a metric (here, booking errors) for each arm during a monitoring window
3
Detect a regression If the treatment arm is statistically worse than control, that's a regression — no threshold-guessing required
4
Roll back automatically The flag reverts to the control variation and logs why. Everyone is back on the safe version within minutes

The key idea is the control arm. A plain "turn it on for everyone" has nothing to compare against — you can only eyeball a dashboard. A guarded release always keeps a healthy control group, so the comparison is apples-to-apples and the rollback decision is statistical, not a hunch. This is why guarded rollouts cap the treatment at 50% — the other half is the yardstick.

⚙️
Starting one: the flag, the metric, the rollout How the traffic conductor kicks off the release over the API

A guarded release needs three things: a flag with a control and a treatment variation, a metric to guard on, and the rollout itself. In this app the flag is new-checkout-flow (control = stable checkout, treatment = the buggy new one) and the metric is booking-error. The traffic conductor starts the release over the LaunchDarkly REST API with a semantic-patch instruction:

// scripts/traffic-conductor.js — start a guarded rollout on the flag
{ kind: 'startAutomatedRelease', releaseKind: 'guarded',
  originalVariationId: falseId, targetVariationId: trueId,
  randomizationUnit: 'user',
  stages: [{ allocation: 50000, durationMillis: 300000 }], // 50%, 5-min window
  metrics: [{ key: 'booking-error', isGroup: false }],
  metricMonitoringPreferences: { 'booking-error': { autoRollback: true } } }

Most teams do this with two clicks in the LaunchDarkly UI — the API path here just lets the demo re-arm itself every morning. Guarded rollouts can also be started, watched, and stopped entirely from the flag's Monitoring tab.

📸
Screenshot placeholder: Start a guarded rollout
The "release" configuration on the Targeting/Monitoring tab: variations, allocation, guard metric, auto-rollback toggle

Configuring the guarded rollout: 50% treatment, guarded by Booking Errors, auto-rollback on

📉
The guard metric What LaunchDarkly watches, and how the app feeds it

The guard is the booking-error metric — an occurrence metric where lower is better. When a checkout fails, the app fires the event, and LaunchDarkly attributes it to whichever arm that user was bucketed into. Because the treatment (new) checkout fails every time and control almost never does, the two arms diverge immediately.

Crucially, the event is fired against the same user context that evaluated the flag, so attribution is exact. This app fires it both server-side (so cheap API traffic feeds the guard) and client-side (so it also lands on the session-replay timeline):

// src/routes/bookings.js — server-side, same context that evaluated the flag
if (useV2Checkout) {
  track('booking-error', req.sessionId, { http_status: 500 });
  throw Error('CheckoutV2Error: payment intent missing'); // 500
}
🔵
Any metric can guard a release

Errors are the obvious one, but you can guard on latency (p95), a custom conversion, or any metric in LaunchDarkly. The regression check compares treatment vs control on that metric.

Automatic rollback & the control arm Why it reverts on its own, and why it never exceeds 50%

When the guard detects the treatment arm is worse, LaunchDarkly performs the rollback with no human in the loop: it sets the flag's rule to serve the control variation to everyone and records a "reverted automatically after detecting a regression" event. In this app that lands the flag back on the stable checkout, and the whole arc — start → spike → rollback — usually completes in a couple of minutes.

Because a guarded release requires a control group, treatment is capped at 50%. That's a feature, not a limit: it guarantees there's always a healthy population to measure against and to protect. The demo also keeps a time-based backstop that force-reverts if traffic is ever too low for the guard to reach significance — belt and suspenders.

📸
Screenshot placeholder: Booking-error regression graph
Monitoring tab: the Booking Errors chart showing treatment far above control, with the rollback marker

Treatment-arm booking errors climb above the control arm, tripping the guard

🔥
The daily 7am checkout incident The whole choreography, running unattended every morning

The demo runs the entire arc on its own, daily, against the 24/7 traffic:

  • 7:00 ET — the conductor starts a guarded rollout of new-checkout-flow at 50%, guarded by booking-error.
  • Treatment-arm users get the new checkout and hit a "500 — Checkout Unavailable" screen; control-arm users check out normally.
  • A short checkout surge (cheap API traffic + a burst of real browser sessions) feeds the guard fast and records treatment-arm session replays of the failure.
  • LaunchDarkly detects the regression and rolls back to the stable checkout, typically within a couple of minutes.
  • The conductor re-arms clean for the next morning.

Pair this page with Session Replay: the treatment-arm failures are recorded, so you can watch a real user hit the broken checkout during the exact window the guard was deciding.

📸
Screenshot placeholder: "500 — Checkout Unavailable"
The app's booking page for a treatment-arm user: the red 500 banner + the "✨ NEW CHECKOUT" badge

What a treatment-arm user sees during the incident — the failure that trips the guard

Watch the next rollback

The incident fires daily at 7am ET. Open the flag's Monitoring tab to watch it live, or check the flag history afterward to see the automatic revert and the booking-error graph that caused it.

See the replays →