You just built your application and you're preparing to deploy it. Then you ask the question:
What happens to my application and its clients and services when I make changes and deploy?
If you're building a side project with only a few users, it's easy to simply redeploy and not bother too much about what happens during deployment.
However, as your application grows, deployment itself becomes an important part of software engineering. Clients and services continue interacting with your application while you're replacing it with a newer version, so how do modern applications continue serving requests without going offline?
There are four common deployment strategies, each approaching this problem differently.
Table of Contents
- Restart / Recreate
- Rolling Deployment
- Canary Deployment
- Blue-Green Deployment
- Choosing the Right Deployment Strategy
- Deployment Isn't Just About Code
1. Restart / Recreate

Restart (also known as Recreate) is the simplest deployment strategy.
In this method, deploying a new version of your application simply turns off the current version and starts the newer one. It's simple, easy to understand, and requires very little infrastructure.
The downside is that it introduces a temporary blackout. While the old version has stopped and the newer version is still starting, clients and services are unable to communicate with your application.
Rollback also isn't immediate. If something goes wrong after deployment, you need to redeploy the previous version, introducing another period of downtime.
This deployment strategy is rarely used for customer-facing production applications because of the downtime it introduces, but it's perfectly reasonable for personal projects, internal tools, or applications where a brief outage is acceptable.
2. Rolling Deployment

Rolling deployment approaches the problem differently.
Instead of replacing every running instance at once, you gradually replace instances of the older version with newer ones. As each new instance starts, health checks validate that it is healthy before traffic is routed to it. This process continues until every running instance has been replaced.
Unlike the restart strategy, clients and services can continue communicating with your application throughout the deployment. Rolling deployment is also the default deployment strategy in Kubernetes (K8s).
One important caveat is that rolling deployments generally require two or more running instances of your application. If you only have a single instance, there is nowhere for traffic to go while that instance is being replaced, making it effectively a restart deployment.
Rolling deployments also introduce a new challenge.
During deployment, two versions of your application coexist. Requests are routed to different instances through a load balancer, meaning clients and services may communicate with either the older or newer version at the same time.
This means both versions must remain compatible throughout the deployment. If the newer version no longer understands requests, shared data, or contracts produced by the older version, parts of the system can begin failing even though the deployment itself is progressing successfully.
Rolling deployments also make rollbacks more involved. Since the older version is being gradually replaced, a rollback usually means performing another rolling deployment back to the previous version rather than instantly switching traffic to a fully preserved environment.
Rolling deployment is one of the most widely used deployment strategies because it provides zero downtime without requiring two complete environments. The tradeoff is that both versions of your application temporarily coexist, making backward compatibility an important part of the deployment process.
3. Canary Deployment

Canary deployment approaches the problem differently.
Instead of gradually replacing every running instance equally, it changes how traffic is routed during deployment.
Only a small percentage of clients and services are routed to the newer version while the majority continue communicating with the older version.
For example:
- 95% → Older version
- 5% → Newer version
The newer version is continuously monitored using health checks and production metrics. If everything looks healthy, more traffic is gradually shifted to the newer version until it eventually serves all requests.
The idea is to limit the number of clients and services exposed to a new version until its stability and correctness have been validated.
Like rolling deployments, both versions of the application coexist during deployment. This means the same compatibility concerns still apply. If the newer version no longer understands requests, shared data, or contracts expected by the older version, parts of the system can begin failing even though only a small percentage of traffic has been routed to it.
One advantage of canary deployment is that if a problem is detected early, traffic can simply stop being routed to the newer version while the issue is investigated. Since only a small percentage of clients and services were exposed to the new version, the impact of a bad release is significantly reduced.
Canary deployments are commonly used when reducing the impact of a bad release is more important than deploying every client to the newer version immediately.
4. Blue-Green Deployment

Blue-Green deployment approaches the problem differently.
Instead of gradually replacing instances or gradually shifting traffic, an entirely new environment is deployed alongside the current one.
Initially, all traffic continues flowing to the Blue environment while the Green environment is deployed and validated using health checks.
Once the Green environment has been validated, traffic is switched from Blue to Green.
This gives us zero downtime throughout the deployment process. It also provides one of the simplest rollback strategies. If something goes wrong after deployment, traffic can simply be routed back to the Blue environment while the issue is investigated.
The tradeoff is infrastructure cost. Since both environments are running at the same time, you're effectively running two versions of your application during deployment.
Blue-Green deployment is commonly used for applications where zero downtime and rapid rollback are important requirements.
5. Choosing the Right Deployment Strategy
There isn't a perfect deployment strategy. Each one comes with its own tradeoffs.
Restart deployment optimizes for simplicity.
Rolling deployment optimizes for resource efficiency while allowing clients and services to continue communicating with the application during deployment.
Canary deployment optimizes for reducing the impact of bad releases by limiting the number of clients and services exposed to newer versions.
Blue-Green deployment optimizes for zero downtime and provides one of the simplest rollback strategies at the cost of running two environments during deployment.
Personally, I tend to use Restart deployments for personal projects and Rolling or Canary deployments for applications with active clients and services. The right deployment strategy ultimately depends on the availability requirements, risk tolerance, and infrastructure of your application.
6. Deployment Isn't Just About Code
One thing that's easy to overlook is that deployments don't only change application code. They often change data too.
Rolling back code is usually straightforward. Rolling back database changes can be significantly harder, and in some cases, nearly impossible.
Imagine you're deploying a new version of your application that replaces a full_name column with a name column.
If the older column is removed before every application instance has been updated, older versions of the application may begin failing because they still expect full_name to exist.
This becomes especially important during Rolling and Canary deployments where multiple versions of the application are communicating with the same database at the same time. Even Blue-Green deployments are not immune to this. Routing traffic back to the older environment does not automatically restore database changes that have already been applied.
One common approach is the expand-and-contract pattern.
First, expand the schema by introducing the new structure while keeping the existing one.
Next, deploy application code that remains compatible with both versions and backfill older data where necessary.
Once every application instance is running the newer version, the older schema or contract can safely be removed.
Top comments (0)