# When to cut traffic to a warm standby instead of a rolling replace

> Decide when to cut all traffic to a warm standby on an owned backend, and when a rolling replace should stay the default.
> By Dave · 2026-09-25
> Source: https://otf-kit.dev/blog/blue-green-vs-rolling-owned-backend

[Rolling deploys](https://otf-kit.dev/blog/rolling-deploys-owned-backend) are the default on an owned backend: one fleet, old and new serving together until the old instances are gone. Blue-green is the other move. A second stack stays warm, and you cut traffic to it in one switch.

The choice is whether the two builds can share a request path, how fast you must leave a bad build, and whether the last good state still exists after the new code has written data. A second full stack idles until the cut. Idle memory is a bill you take on purpose.

Surge, unavailability, and instance order belong to the rolling deploys piece. This post decides when you stop mixing versions and move a load balancer, a Service selector, or a weighted route.

## Cut when versions must not share a request path

A mixed fleet is safe only while a request can land on either version and finish correctly.

A wire change breaks that. The new process speaks a shape the old one rejects: a required field, a renamed header, a content type, an RPC the old binary does not register. Callers split across the two shapes. A retry draws the same mix. Failures follow the ratio.

A schema the old process rejects fails the same way in stored data. Green writes a column, an enum, or a payload blue cannot read. Traffic left on blue errors, including reads of rows green already wrote.

The write path is stricter. When every peer must already speak the new contract — a lock format, an outbox event, a cache key — the mixed fleet splits writes. Soak green on real dependencies with user traffic held off: same database, same queues, same downstreams. Move the balancer or Service selector once, and green becomes the only version taking production requests.

Rollback is that switch in reverse. It works while blue is up and can still serve the data that now exists. Keep blue warm until you trust the cut.

## Cut when time-to-rollback matters more than spare capacity

A gradual replace unwinds through startup, readiness, and the surge budget. That wait fits a slow failure: latency on a slice, an error rate that climbs with the mix. It fits an immediate failure poorly. A bad config, an auth check that rejects every token, or a startup path that corrupts a shared cache should be left before the next health interval.

A flip moves a selector or a weight from 100/0 to 0/100. The bill is two full stacks, both ready, for as long as the old color stays. On a small service the second Deployment is cheap beside the time you get back. On a memory-heavy tier the idle half is the decision. The same heap doubles resident memory until blue scales down.

A ramp, small weight then larger, stays gradual. Use it when versions coexist and the blast radius should stay limited. Blue-green here means the full cut onto a stack that was already warm.

![Blue-green cutover switch versus rolling batch replace side by side](https://cdn.otf-kit.dev/blog/blue-green-vs-rolling-owned-backend/inbody1-20260925a.png)

## Stay gradual when a flip would not restore the last good state

Two colors, one database. Drop a column, rewrite data, or change what a field means, and blue cannot read what green wrote. The selector can point at blue again. Blue then fails on current rows. Sequence the schema as expand, deploy, contract. Expand keeps the old shape valid for every process still running. Deploy writes both shapes, or writes the new one so old code ignores it. Contract removes the old shape only after nothing that might still run depends on it. The standby hands you the previous binary, which has to read the rows green left behind.

Call green warm only once real requests can succeed. Pools are open. Hot-path caches are filled, or misses are priced and the downstream is sized. A shadow load has run that path against production dependencies, users still on blue. A readiness route that returns 200 before any real query will take the herd. Readiness is the ability to do the work. A first wave that opens pools and times out downstreams survives one probe, then falls over.

[Graceful shutdown and drain](https://otf-kit.dev/blog/graceful-shutdown-drain-owned-backend) still apply on the way out. In-flight work on blue continues after the selector moves. Drain it. New requests go to green. Old ones finish, or hit their deadline, on blue. Scale blue down after the drain, once you are finished with the reverse switch.

## Stay gradual when versions can share the path

Stay on a rolling replace when the versions can coexist. A parser, a timeout, a log field, a query that returns the same rows: one contract, and a retry may land on either build. This change ships on the fleet you already have.

Stay there when the copy will not fit. A cache sized to the host, a heap tuned to the box, or one GPU means the overlap is another tier. Rolling spends the surge already configured, a slice of the same fleet.

Stay there when the fault should hit a slice. A slower query or a higher error rate shows while most instances still run the old build. Stopping the replace leaves most callers on the last good build. A full cut reports the same bug after every caller has moved. Prefer the fast reverse across all traffic, or the slower slice with most of the fleet still on the old build.

A slice can still stampede a cache, storm a lock, or retry into a downstream. [Circuit breakers](https://otf-kit.dev/blog/circuit-breakers-owned-backend) cap the amplification while you halt. Whether the two versions can share a path stays a separate decision.

| | Blue-green cutover | Rolling gradual replace |
| --- | --- | --- |
| Traffic | One switch of all new requests onto a warm stack | Batches, with old and new serving together |
| Capacity | Two full stacks for the overlap | One fleet, within maxUnavailable and maxSurge |
| Fits when | A shared path would fail, or rollback must beat the next health interval | Coexistence is safe, spare capacity is a slice, or the fault should stay small |
| Rollback | Reverse the selector or weight while the previous color is up and can read current data | Stop the replace; the wait is startup and readiness |
| Data | The flip leaves migrations and other writes where they are | Mixed versions split writes when the contract has changed |
| You operate | Two Deployments, a selector or ingress weight, then a drain | One Deployment; the controller walks the replace |

![Traffic flip to green warm standby with blue drain for rollback](https://cdn.otf-kit.dev/blog/blue-green-vs-rolling-owned-backend/inbody2-20260925a.png)

The flip puts one version on the request path. The batch replace stays mixed until the old instances are gone.

## What you move, and what stays up

Kubernetes Deployments perform the gradual replace with maxUnavailable and maxSurge on one Deployment. The cut is two Deployments and a selector or ingress weight you move once green is warm. Warm means pools open, caches filled or misses priced, a shadow load finished, and readiness held closed until then. Drain blue before scaling it to zero. In-flight requests outlive the selector change, and the time blue stays up is the rollback window.

Where coexistence is safe and the idle cost is already accepted, keep the gradual replace. Where a shared path would fail, or leaving a bad build cannot wait on startup and readiness, cut to the warm standby and keep the previous color until that cut has earned it.

## Sources

- [Rolling deploys on an owned backend](https://otf-kit.dev/blog/rolling-deploys-owned-backend)
- [Graceful shutdown and drain on an owned backend](https://otf-kit.dev/blog/graceful-shutdown-drain-owned-backend)
- [Circuit breakers on an owned backend](https://otf-kit.dev/blog/circuit-breakers-owned-backend)
- [Kubernetes Deployments](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)
- [Blue/Green Deployments on AWS](https://docs.aws.amazon.com/whitepapers/latest/blue-green-deployments/welcome.html)