Rolling Deployment
Concept
Rolling deployment upgrades a fleet incrementally, a batch at a time, replacing old instances with new ones as it goes — instead of the all-at-once cutover of recreate, or the fully-duplicated second environment of blue-green. Kubernetes makes this the default Deployment update strategy: as new pods running the target version come up, old pods are terminated, and the process continues batch by batch until every instance is running the new version. Because no second full-size environment is required, rolling deployment is cheaper to run than blue-green while still giving up the "all-at-once" blast radius of recreate — a bad release only ever affects the batch currently in flight, not the whole fleet at once.
The mechanics are governed by two parameters, maxSurge and maxUnavailable. maxSurge caps how many extra instances beyond the desired count can exist temporarily during the rollout — allowing new pods to come up before old ones are torn down, so there's never a capacity gap. maxUnavailable caps how many instances can be offline at once during the update — a lower value keeps more capacity online throughout the rollout (slower, safer) while a higher value updates faster at the cost of temporarily reduced capacity. Setting maxUnavailable to zero gives the strongest guarantee — the desired replica count never drops during the rollout — at the cost of always needing at least one surge instance to make room for each new pod before an old one is removed.
Tradeoffs
| Dimension | Recreate | Rolling Deployment | Blue-Green |
|---|---|---|---|
| Downtime | Full outage during cutover | None, if maxUnavailable keeps enough capacity online throughout |
None — cutover is instant |
| Infrastructure cost | Lowest — single environment | Low — no second full environment | Highest — double capacity during rollout |
| Blast radius on a bad release | 100% immediately | Capped by batch size, but grows as the rollout proceeds — by the time it's caught, some fraction of the fleet is already on the bad version | Briefly 100% until detected, but rollback is instant |
| Rollback mechanism | Redeploy the old version everywhere (same as forward deploy) | No idle "old" environment to fall back to — rollback means rolling forward again with the previous version, batch by batch | Instant — flip traffic back to the still-running old environment |
| Version mixing during rollout | None | Old and new versions coexist for the whole rollout duration | Only briefly, during the health-check window before cutover |
The central tradeoff against blue-green is rollback speed: rolling deployment doesn't keep an idle old environment sitting ready, so "rolling back" is mechanically identical to rolling forward with the previous version — there's no instant traffic flip, just another gradual rollout in reverse.
When to use / when not to
- Use rolling deployment as the default for resource-constrained environments that can't justify doubling capacity for blue-green, but where recreate's full downtime is unacceptable — this is the common middle ground, and Kubernetes' native support makes it close to free to adopt.
- Tune
maxUnavailabletoward zero (and rely onmaxSurgefor headroom) when the service has hard availability requirements during deploys; accept a highermaxUnavailablewhen deploy speed matters more and brief, partial capacity reduction is tolerable. - Pair rolling deployment with per-batch automated verification, not just a single end-of-rollout check — since old and new versions coexist for the whole rollout, a bad release detected only at the end has already been serving a growing fraction of production traffic the entire time.
- Prefer blue-green instead when instant rollback matters more than the infrastructure savings — rolling deployment's batch-by-batch rollback is not a substitute for an instant traffic-flip when minutes matter during an incident.
Common pitfall
Assuming rolling deployment gives the same rollback speed as blue-green because both are "zero-downtime" strategies. They aren't equivalent: blue-green keeps a full, idle, already-warmed-up old environment ready for an instant traffic cutover, while rolling deployment has no such thing sitting in reserve — reverting means running another rollout, batch by batch, in the opposite direction, which takes just as long as the original rollout did. A team that assumes "we can roll back fast" without having actually timed a rolling-deployment rollback under realistic conditions is likely to discover, mid-incident, that "rollback" here means minutes-to-tens-of-minutes, not seconds.
The other half of this pitfall is treating batch-by-batch progression as automatically safe without an explicit, automated stop condition wired to verification. If verification of an early batch fails but there's no automated halt — just a log entry or a dashboard status a human might not notice in time — the rollout keeps advancing to later batches on a version already known to be bad, which defeats the entire point of batching in the first place.
Engineering Lens
The Principal-level distinction here isn't "we do rolling deployments instead of recreate" — it's whether the rollout has an automated, verified stop condition per batch, and whether the team has actually measured (not assumed) how long a real rollback takes under this strategy. Rolling deployment buys real blast-radius control over recreate, but only if a bad batch actually halts the rollout automatically; and it buys real cost savings over blue-green, but at the price of a rollback that's structurally slower — being explicit about that tradeoff, rather than treating all "zero-downtime" strategies as interchangeable, is what separates understanding the pattern from just enabling it.