Building a modern application often involves building it as a microservice, which provides developers with more flexibility and agility in terms of deployment options. However, deployment can either be a joy or a nightmare, depending on the strategy used, whether it's deploying microservices, testing new features, updating a business logic, or releasing a new version entirely? With every code change pushed, comes the risk of potential failures, which could be as a result of bad code quality or unexpected bugs, and this can potentially disrupt the user's experience.
Hence, picking an efficient deployment strategy is key to mitigating these deployment risks and not having to constantly disrupt your user’s experience by going into downtimes or completely having to go offline whenever there is something to be deployed.
This article aims to highlight the various progressive delivery forms of deployment available, with hopes of providing a clear guide to choosing a suitable deployment strategy that best suits your needs. The following proven deployment techniques make it quite easy to make improvements to our applications, introduce new services and features, test functionality, quickly identify/eliminate vulnerabilities, and safely deliver the right features faster and with confidence.
What is Progressive Delivery
Progressive delivery is an emerging approach to accelerating DevOps as it combines the principles of Continuous Integration and Continuous Delivery (CI/CD), with modern software development practices which facilitate faster code shipping, reduce risk and improve the user's experience.
The fundamental idea behind progressive delivery is that developers and organizations can incrementally roll out and deliver new features to users, with safeguards and fine-grained control levers that enable the teams to minimize the risks that come with continuously pushing new features to the production environment, while monitoring the health of the application at each stage of the progressive delivery process. And if anything should go wrong, quickly revert to a stable stage.
In progressive delivery, Feature Flags are important in managing the blast radius of these deployed features. They provide feature toggles that enable developers to deploy features to a subset of users based on attributes such as geolocation or other custom profiles. They also enable rolling back these features a toggle away if they don't work as intended. Developers can then gradually expand the radius of their deployments by implementing incremental changes based on the received feedback from the initial release.
Phased rollouts can be considered a subtle variation of progressive delivery. In the phased rollout deployment methodology, you can manage your product releases more effectively by breaking them up into smaller implementations that can be tested and implemented easily on smaller segments of users. These users are typically the most advanced and active ones whose activity provides the best feedback before being released to wider audiences.
This approach allows developers to incrementally introduce new functionalities and features to a smaller group of end-users but also minimize the possible impact this can have on the entire user base, by obtaining feedback to help improve the product further. As these phased rollouts progress, the information gathered in the early phases of these phased rollouts can then be used to guide the remainder of the rollouts process, so that there are fewer issues or errors while at the same time, gradually accustoming the users to the new rollouts.
Twitter is an example of a company known for using the progressive app delivery method of deployment to efficiently roll out new features to its user base, because phased rollouts enable developers to release smaller and more frequent updates for their apps so users can receive new features more quickly, without exposing themselves to bugs. The two core essential characteristics of phased rollouts are:
- Experimentation: This technique is used to evaluate how an app performs when certain features are implemented in production, for example using A/B testing to learn which version users prefer. A typical use case scenario would be when a team tests the effectiveness of different designs of a sale button to different subsets of users, to see how each design influences conversions and then uses the most successful design as the final rollout.
- Feature flagging: This technique manages the rollout of a new feature to a limited audience so that its impact can be monitored. It typically involves turning certain features on or off for a subset of users, reducing any risk. Most teams use third-party services such as the ConfigCat feature flag service for their feature flagging.
- A safe method for testing new implementations in production.
- It facilitates observability which makes it easier to quickly contain bugs and unexpected issues.
- Since the deployment is broken up into parts, it improves operational management.
- It reduces downtime, limits the blast radius, and lets us learn from the process.
- Through a series of experiments, phased rollouts enable a system to be flexible and powerful through numerous experiments.
- By using Feature Flags, it's easy to mitigate the risk of continuous deployment.
- As deployment occurs over an extended period, teams must concentrate on a single rollout at a time rather than on the full system rollout as a whole.
- It can take longer to implement a feature as it has to be gradually rolled out.
- Issues encountered in a rollout halt further rollouts until resolved.
- The state of continuous change makes system delivery milestones unclear.
Long ago, in the coal mining industry, canaries were used to detect the presence of harmful levels of toxic gas as an early warning system (because canaries were very sensitive). Thus, Canary releases were named after the well-known expression, "canary in a coal mine."
Canary release is a version testing method used for reducing the risk of introducing a new software version into production. This is done by first deploying the new version of the application to a portion of the production platform/infrastructure with no users on it, and then gradually routing a subset of users traffic to this section of the platform which exposes them to the new version.
The chosen users can be decided based on different strategies: a simple approach is to randomly select users; while some organizations release the new version to internal users and employees before releasing it to external users; another more sophisticated approach is to choose users based on custom profiles such as demography, location, etc.
As more confidence is gained in the new version and no errors are detected, more servers in the infrastructure can then be made available for it and more users sent to it, but if the new version has any problems or major bugs, the rollback strategy is to reroute these users back to the old version until the problem has been resolved.
Differences between Canary Releases and Feature Flags
Canary releases are sometimes confused with feature flags as they also deal with incremental feature releases, but canary releases are different from feature flag releases since feature flag releases are used to expose a specific feature to a small group of users. While Canary releases expose a specific version of the entire application or service to a portion of the platform's infrastructure and then direct some of this user traffic to this new version.
But though a Canary release and a Feature flag vary, they can both be used together to achieve an efficient release. A typical use-case would be wanting to release the new version as a Canary release but not wanting to have all the features available at first. Using a feature flagging service such as ConfigCat is the best solution for a scenario like this. ConfigCat enables you to implement feature flags or feature toggles in your application, and automatically add emergency kill switches to facilitate the gradual rollout of more features as feature testing is done. I dare say this is the best of both worlds.
- Reduces the probability of releasing a new version that negatively impacts a large number of users, hence an ability to test in production.
- Increases the value of the new version since user behavior can be observed and well-instrumented.
- It's relatively easy to revert to the old version if a problem is detected by simply rolling back traffic to the old version.
- Easily restrict access to specific audiences, individual users, or a certain percentage of users
- It is relatively easy to automate the entire release life cycle.
- Easily avoid downtimes.
- Using canary releases comes with the drawback of having to manage multiple versions of your application simultaneously.
- If the distributed application is installed on the user’s device, there is less control to efficiently use canary releases.
- When releasing canaries, database changes between the old version and the new version would have to be managed.
- Needs resources to maintain the old system and the new system
With a ring deployment, you manage the deployment risk by providing new features to different groups gradually. These groups are represented by a series of rings, starting from a small ring consisting of a group of few users and then gradually expanding to an ever-growing series of rings until you include all your users.
There can be multiple production environments in a ring-based deployment. A limited number of users can then be served by each production environment. It is similar to Canary Release but Ring-based deployments, on the other hand, allow you to maintain as many production environments as you want and over time, new releases are deployed to the rings one by one until all rings are updated.
And just like with most deployments, in-ring deployment, feature flags can help you toggle certain features or functionality you aren't certain about in a ring.
- Gradually test your application before it is made available to all users
- It's easy to roll back when something goes wrong with a ring.
- It is easy to gather feedback from each ring.
- It's easy to control the radius of each feature as it is subject to the size of the ring (number of users in a ring)
- Feature flagging can be used for fine-tuned control.
- Slow delivery timeline as releases have to be made ring by ring.
- Resources are split across rings.
- Problems occurring in rings can derail the deployment timeline.
With progressive delivery, you can more effectively track, support, and control your deployment and progressively deliver new features and functionalities to your users, as it combines modern software deployment practices such as Feature Flagging, A/B testing, etc to facilitate faster code shipping, reduce risks associated with traditional deployments such as downtimes and greatly improve users experience.
If you want to move fast and with confidence when deploying, even while breaking things, the different forms of progressive delivery provide better support and control for these incremental deliveries even while in production. By taking a customer-centric approach, progressive delivery increases resilience as well as decreases deployment downtime, and also embraces a smooth transition for end-users in a sense.