Practice this topic in a realistic system design interview
Writing and testing code is only half the job. The other half is getting that code in front of real users without taking the system down.
A deployment strategy is the plan for moving a new version of your application into production safely.
Every team has a deployment strategy, even if nobody calls it that. Restarting a process, replacing containers one group at a time, or running a second environment and moving traffic to it are all deployment strategies.
Each strategy answers the same question in a different way: how do we change the system while people are using it?
This chapter explains the common deployment strategies, what each one is good at, where each one can hurt you, and how experienced teams choose between them.
A live system is not sitting still while you deploy. It has open connections, requests already running, caches full of data, background jobs in progress, and users who notice errors quickly.
A good deployment strategy answers a few practical questions:
Most production systems use one of these five strategies, or a combination of them.
Stop the old version, then start the new version.
This is the simplest strategy, and it always has downtime. It can be fine for internal tools, batch jobs, small services, or applications with planned maintenance windows. It is also still used for some stateful systems where two versions cannot safely run at the same time.
Replace servers or containers in small batches.
The old version keeps serving traffic while the new version comes online. This is the default style in Kubernetes, AWS ECS, and many other deployment tools. It avoids downtime without needing a second full copy of production.
The catch is that old and new versions run side by side during the rollout. Your application, database schema, messages, and APIs must be able to handle that mixed-version period.
Run two complete environments.
"Blue" serves production traffic. "Green" is a parallel environment running the new version. After green is checked, traffic switches from blue to green in one step.
Blue-green gives very fast rollback because you can point traffic back to blue. The trade-off is cost: during the switch, you are running two environments. Database changes still need care because blue and green often share the same database.
Send a small slice of real traffic to the new version, watch the metrics, then expand if things look healthy.
A typical canary rollout might go from 1% → 5% → 25% → 100%, with checks at each step. This is a strong fit for risky changes because only a small percentage of users sees the new version at first.
The cost is extra operational work: traffic splitting, metrics that can separate old and new versions, and clear rules for when to continue or roll back.
Copy production traffic to the new version, but do not use its responses.
Real users still get responses from the old version. The new version is tested with realistic traffic without being responsible for user-facing results.
Shadow deployments are useful for performance-sensitive rewrites, such as search, ranking, recommendation, or payments code. The hard parts are routing copied traffic, comparing responses, and making sure the shadow version does not create real side effects such as duplicate charges or extra emails.
The strategies differ in a few important ways: downtime, cost, rollback speed, blast radius, and complexity.
Blast radius means how many users or systems can be affected if the new version is bad.
Use this table as a quick map. It shows what you gain and what you give up with each strategy.
| Strategy | Downtime | Extra Infrastructure | Rollback Speed | Blast Radius | Complexity |
|---|---|---|---|---|---|
| Recreate | Yes | None | Slow (redeploy old) | Whole fleet | Very low |
| Rolling | None | Small temporary extra capacity | Moderate (roll back batch by batch) | Grows over the rollout | Low |
| Blue-Green | None | Double during switch | Very fast (flip back) | Whole fleet at switch | Medium |
| Canary | None | Small | Fast (shift traffic away) | Limited to canary % | High |
| Shadow | None | Extra capacity for copied traffic | Not applicable (not user-facing) | Zero user impact | High |
No strategy is best for every system.
A small internal API might be fine with recreate. A payments service shipping a risky change probably wants canary plus rolling. A team rewriting a search engine may want shadow traffic before any real users touch the new code.
The names are useful, but the real decision comes from the shape of the change.
Low-risk changes can usually go through a normal rolling deployment. Examples: copy changes, small bug fixes, dependency bumps, or additive features hidden behind a flag.
High-risk changes deserve more care. Examples: algorithm rewrites, schema-heavy changes, payment logic, ranking logic, or anything that could affect latency. These often use canary or shadow deployment, with feature flags layered on top.
A small B2B tool used during office hours may tolerate a maintenance window. A global payments API cannot treat one minute of errors as acceptable.
The more expensive downtime is, the more careful the rollout needs to be.
During an incident, the team cares about one thing first: how fast can we get users away from the broken version?
| Strategy | Typical Rollback Window |
|---|---|
| Recreate | Minutes to tens of minutes (redeploy the old version) |
| Rolling | Minutes (reverse the rollout) |
| Blue-Green | Seconds (flip traffic back) |
| Canary | Seconds to a minute (shift traffic away) |
| Shadow | Not applicable; new version is not in the user path |
Blue-green and canary make rollback mostly a traffic-routing decision. That is their biggest advantage. You do not have to rebuild or redeploy first; you move traffic away from the bad version.
Most deployment strategies work best when application servers are stateless. The servers can come and go, but the database, cache, and queues keep running.
For rolling, blue-green, and canary deployments, schema changes must be backward compatible. That means the old code and the new code can both work with the database at the same time.
A safe pattern looks like this: add new columns before reading them, write both old and new formats during the transition, and drop old columns only after the old code is gone.
Feature flags help because the code can be deployed first, the schema can change in small safe steps, and the feature can be turned on later.
Blue-green needs two environments during the switch. Canary needs traffic splitting and metrics per version. Rolling usually needs a little extra capacity while new instances start.
The cloud bill is often not the hardest part. The harder cost is building the right habits and tools: good health signals, traffic controls, rollback automation, and the discipline to use them consistently.
A 1% canary during a quiet hour may not send enough traffic to prove anything.
Traffic shape matters too. WebSockets, gRPC streams, video calls, and other long-lived connections make deployments harder because connections do not simply jump from the old version to the new one.
The strategy has to fit how the system is actually used.
In real production systems, teams rarely use only one strategy.
A common pipeline looks like this:
This pipeline uses each step for a different kind of safety:
Feature flags often sit on top of this flow. They let the team deploy code now and turn on risky behavior later.
Other combinations show up too:
Think of these strategies as tools in a toolbox. Mature deployment pipelines usually combine them.
One of the most important ideas in modern deployment is this:
Deploying code and releasing a feature are not the same thing.
Feature flags separate those two steps. You can deploy code to every server with the feature turned off. Later, you release the feature by flipping a flag, perhaps for only 1% of users at first.
This is one reason trunk-based development works at scale. Teams deploy small changes often, keep risky behavior behind flags, and release product behavior on a separate schedule.
A deployment strategy is only as good as the signals behind it.
The rollout system needs to answer a simple question: is the new version helping or hurting?
The best deployment signals are usually the same signals you use to measure the service itself:
In a canary rollout, comparing old and new versions is fairly direct. In a rolling deployment, the fleet is mixed, so comparison is harder. In blue-green, the most useful comparison happens before and after the switch.
A deployment with no useful signals is just hope with a progress bar.
Use this as a practical starting point.
| Situation | Reasonable Strategy |
|---|---|
| Internal tool, single instance, downtime acceptable | Recreate |
| Stateless web service, several instances, steady traffic | Rolling |
| Critical API where rollback speed matters most | Blue-Green |
| High-risk change, large user base, metrics split by version | Canary |
| Performance-sensitive rewrite, side effects under control | Shadow |
| Risky feature, reliable feature flag system | Rolling deploy + feature flag rollout |
| Schema change | Rolling deploy + backward-compatible migration in stages |
| Long-lived connections (WebSockets, streams) | Rolling with careful drain + reconnect handling |
These are starting points, not rules. A mature system usually layers strategies based on the risk of the specific change.
The same mistakes show up again and again, no matter which strategy a team chooses.
The root problem is usually the same: the rollout looks smooth, but the team is not measuring the right things.
A deployment strategy is the plan for moving code into production safely. Every team has one, whether it is named or not.
Recreate, rolling, blue-green, canary, and shadow each make different trade-offs. The right choice depends on risk, downtime cost, rollback speed, infrastructure cost, traffic shape, and database compatibility.
Recreate is simple but has downtime. Rolling avoids downtime but temporarily mixes versions. Blue-green gives fast rollback but needs a second environment during the switch. Canary limits blast radius by starting small. Shadow tests a new version with copied traffic without affecting users.
Most production pipelines combine these strategies. A common flow is staging, then canary, then rolling, with feature flags layered on top.
Two ideas tie everything together. First, deploy and release are different: you can ship code before users see the behavior. Second, a strategy is only as good as its signals. Error rate, latency, saturation, and business metrics tell you whether to continue or roll back.
Database changes deserve special care because many strategies run old and new code at the same time. Schema migrations must stay backward compatible during that window.
The practical lesson is simple: pick the safest strategy that matches the risk of the change, the shape of the traffic, and the maturity of your deployment tooling.
10 quizzes