#30 Worth To Know: Common Deployment Strategies
Choosing the right deployment strategy is critical to efficient software delivery. In this post, I describe four battle-tested approaches: basic, blue-green, canary, and rolling deployments.
The term "deployment strategies" is used in various areas. For example, when figuring out if we should go with a single deployment unit (e.g., using monolith) or multiple deployment units (e.g., using microservices). But today we will focus on a different case - the way you want to deploy the application you are working on.
Let's examine four deployment strategies: basic, blue-green, canary, and rolling. Why these four? As always, I only want to share with you things that are battle-tested - I have personally used them in various applications.
Basic
I am sure you have at least heard of it - it is also called "big bang" deployment. It is the simplest way to deploy your application. When I started my programming career in 2011, it was one of the most popular.
In short, there is only one version of the application in production. The process involves turning off the application, running the update, turning it back on, and then redirecting all traffic to the new version.
Basic deployment often happens during off-hours to minimize user impact. Your application goes offline temporarily, inaccessible to all users. This approach carries significant risk.
Consider this scenario: The update goes wrong. You must quickly fix the issue or roll back to the previous version. Otherwise, all users face a non-functional application. Rollbacks are not always straightforward, and fixes can take hours. Time pressure mounts. Your team feels the heat. Sweat forms. Customers start reporting outages. You eventually fix it, but you are determined to avoid this situation in the future.
This highlights the main flaw of basic deployment: high potential for problems with no immediate way to redirect user traffic to a working version. On the other hand, it has the advantages of a straightforward deployment process if everything works out and no need to support several application versions simultaneously.
Should you use basic deployment? Remember, simplicity is key. If your application is not critical, your user base is small, and downtime won't cause significant problems (or any at all), then basic deployment might be your best bet. There is no need for complex strategies if a simpler approach meets your needs.
Blue-Green
When one of the requirements is that your application should be always available, one of the strategies is to use blue-green deployments. It solves the main problem of the basic one - there is no downtime during the version update.
In short, a current version of the application runs in production. At the same time, we prepare the new version on another instance and execute verification checks. If everything works fine, we switch the entire traffic to it. The old version stays there in idle as a backup.
Users access the current version in the blue environment, which represents the live production. When the development team initiates a new deployment, the new version goes to the green environment. Here, it undergoes thorough verification to ensure proper functionality and adherence to standards.
Once verified, all traffic shifts to the green environment, making it the new production. In the next cycle, blue will replace green, alternating with each deployment. This approach allows for seamless transitions between versions while maintaining a stable production environment.
It is worth noting that the blue-green strategy is supported by cloud providers in their platform-as-a-service (PaaS) offerings (e.g., Azure App Service or AWS Elastic Beanstalk) and is very easy to set up.
Still, there is one problem. When the update is successful, all users are redirected to the new environment at once. This means that all new features will be available to them. The good news is that there is a concept that can help you with this and is called “feature flags” (another name is “feature toggles”).
They enable activating or deactivating features via configuration, without full application redeployment. This separates code deployment frequency from feature releases. You can gradually roll out features to user subsets, allowing real-world testing and feedback collection before full release. Risk is minimized as features can be instantly disabled, helpful for managing severe issues like memory leaks. However, feature flags require regular maintenance. Neglecting to remove unused flags can lead to code clutter.
The main advantage of using the blue-green strategy lies in its ability to minimize the risk of downtime, as there are always two environments running in parallel. Its main drawback lies in challenges related to the database while running multiple versions of the application. As these challenges are similar for all deployment strategies that use multiple versions, I will describe them in another post.
Canary
If you ask me what is my favorite approach to releasing apps, I will tell you that it is the “canary” one. However, it is also the most difficult to set up, and that is why I recommend it only when your business can get significant benefits from it.
A canary deployment works like this: The current version runs in production. Meanwhile, we set up a new instance with the updated version and run validation checks. If it passes verification, we route a small portion (e.g., 5%) of live traffic to it. We then gradually increase the traffic to the new version, carefully monitoring its performance. If all goes well, we progressively shift more users until the new version handles 100% of the traffic.
The entire deployment can be either automated or done manually. What is worth to observe while increasing the traffic are:
4xx and 5xx errors. If you observe a lot of errors in comparison to the previous version(s), then this is an indicator that something is wrong.
Features are being used less frequently. If the average usage of the shopping cart was 1,000 times per hour in the previous version and now it is used four times, then something is probably wrong.
Latency and response time. If the new version differs significantly from the previous one in response time in the same areas, then something is wrong with the new version.
Customer feedback. Collect and analyze feedback from users exposed to the canary release, directly or indirectly, to identify UI/UX issues or unexpected behavior.
Monitor closely during the gradual release. If problems surface, quickly redirect users back to the stable version. While it is rare, some issues might slip through undetected during rollout. In these cases, rather than rolling back, it is often better to push forward. Create a new canary candidate with fixes and deploy it.
Canary deployments shine through their step-by-step approach. By exposing a new version to a small user group first, you can catch and fix most problems before full-scale release. It also gathers user feedback early. The trade-off? You need expertise and complex infrastructure for traffic routing, monitoring, and version control, so weigh the benefits of early issue detection against the technical demands.
Rolling
Rolling deployment offers another gradual approach, distinct from canary releases. It requires multiple application instances—at least two. The process involves replacing these instances one by one with the new version.
Imagine a scenario with three instances of your application, version 1.0, each handling 33% of user traffic. The rolling deployment of version 1.1 begins:
Update the first instance to 1.1. Now 66% of traffic uses 1.0, and 33% uses 1.1.
If it is stable, update the second instance. Traffic splits 33% on 1.0, 66% on 1.1.
Finally, update the last instance. All traffic now runs on 1.1.
This approach, like canary deployment, lets you test the new version with a subset of users before full rollout. If issues arise, you still have instances running the old, stable version and you can redirect users to it. Unlike canary releases, it doesn't offer fine-grained traffic control - you can't start with just 5% of users or target specific locations.
Summary
When it comes to choosing a deployment strategy, there is no silver bullet (one-size-fits-all) solution. Like many areas of software architecture, the optimal choice depends on your specific context. Consider your application's needs, your team's expertise, available infrastructure, and budget constraints.
Each strategy—basic, blue-green, canary, and rolling—offers unique advantages:
Basic deployment is straightforward and suitable for non-critical applications with minimal downtime impact.
Blue-green provides quick rollback capabilities and reduces downtime.
Canary allows for gradual rollout and early user feedback.
Rolling deployment offers a balance between risk mitigation and resource efficiency.
Remember, the goal is to deploy efficiently and safely, not to implement the most complex system possible. Don't overengineer your deployment process. Start with the simplest strategy that meets your needs and scale up in complexity only when necessary. Regularly reassess your approach as your application and team evolve.
As mentioned before, I will describe database challenges that come with multiple parallel versions of the application in the next post. Stay tuned!
Which deployment strategy do you face the most?