Deployment and release strategies
Read time: 6 minutes
Last edited: May 21, 2020
This guide explains the concepts behind deployment and release strategies made possible by feature flags and feature management.
In this guide, we'll explore:
- The difference between deployment and release
- Different deployment and release patterns
- How to use metrics to track performance
- How to determine flag longevity
- How to avoid technical debt
To complete this guide, you must have the following prerequisites:
- Basic understanding of software delivery patterns, including deployment and release
- Knowledge of your organization's release process
- Proficiency and understanding of LaunchDarkly's flag targeting features, including segments
To learn more about segments, read Building user segments.
You should understand these concepts before you read this guide:
It’s easy to use deployment and release interchangeably, but in a feature-flagging or continuous-delivery environment, they have distinct meanings. It’s useful to understand the differences between them so you can understand the following patterns more clearly.
Deployment is the process of putting executable code in its final destination.
This might be on a server, a client, or any other place the code will run.
Deployment is usually controlled by a technical team, a release manager, or an automated process.
Release is the moment when users get access to new code or features in order to serve a business objective.
Releases can involve many instances of deployment, and may or may not affect all users of your product.
Releases are often run by product or marketing teams.
Using feature flags to deploy code without releasing it publicly is the original meaning of the phrase “dark launching.” When you do a dark launch, your new code or feature is present in your codebase, but not available to everyone.
The flags you use for dark launches are temporary tools to help you make sure that the features you release are reliable, stable, and behaving the way you want. After you fully deploy and release a feature, you can remove these flags.
To learn more about different use cases for feature flags, read Creating flags.
The following patterns are some of the ways we've seen people do deployment and release.
Depending on your business needs, you may want to adopt some of these practices:
In a ring deployment, different groups gradually receive a new feature to manage the risk of deployment. These groups are represented as an expanding series of rings, starting with a small group and growing to encompass all your users.
If you do a ring deployment, choose users for each group based on a set of similar attributes or an opt-in process. Then make features available to those groups. For example, release to internal users first, and then beta users, and then to all users.
In a ring deployment, the release pattern mirrors the deployment pattern, which mitigates against the deployment itself causing a large unforeseen problem.
Jez Humble introduced the concept of a ring deployment in his book Continuous Delivery.
In a percentage rollout, the deployment has already occurred and the release occurs incrementally based on a percentage. The new feature rolls out to 10% of users, then 25%, then 50%, until all users receive the new feature.
In LaunchDarkly, the users who get the new feature in a percentage rollout are randomly selected. After they get the new feature, they retain access to it as long as there is a way to identify them. This kind of sorting is best when your users must log in to use your product, or have accepted cookies.
These releases are useful when you cannot run a beta program, or there is little variation in your targeted user base. If you run a small B2B application with the same 1,000 monthly active users, a percentage-based release is likely to give you an accurate estimate of whether the full rollout is likely to have positive or negative impact on your userbase.
You may want to automate percentage-based releases gradually by increasing the number of users receiving the new feature. You can terminate the release if there are too many errors or a response time exceeds a set threshold.
You can combine ring deployments and percentage rollouts. You first release to selected groups and then use a percentage-based release to roll out to the remainder of your user base.
To learn more, read Percentage rollouts.
A canary release lets you test whether a feature release will have positive impact without affecting your whole userbase. Only a small number of your users see the new feature you release, and you can target by user or segment to determine who those users are.
Ensure that the small group in your canary release is representative of your overall users. For example, a canary release that only goes out to people with the latest phones may miss problems that occur on older versions of a phone's operating system.
You can use a canary release to test both user acceptance and capacity management. If you roll out a new feature to a group and realize that it consumes too many resources, you can turn the feature off and refactor the product without having stressed your infrastructure or caused a bad user experience.
It may make business sense to target a release based on some identifier or segment other than percentages.
For example, a food delivery service could roll out a new feature or set of related features to one medium-size city to test how it works for multiple types of users who must all interact.
If that service makes a change that affects restaurants, drivers, and consumers, all of those users should receive the change simultaneously, since they all perform functions that relate to each other. If the city-wide rollout produces good results, the service can release it to the rest of their user base with confidence.
You might want a flag that affects user permissions or access to be permanent. These flags affect what users can do in your platform, or their entitlements.
You can use an entitlement release to add a feature that is only intended for a portion of your users.
For example, if you had a premium service, you could configure the release so that the feature was only available to people who had paid a membership fee.
You can combine entitlement releases with percentage-based releases or canary releases, but when the release is done, only some users will have access to to the feature.
Your flag's lifecycle doesn't finish when the feature it controls is fully deployed. You need to have metrics and monitoring set up to see human and system behaviors during your rollout, and you need to have a plan to remove temporary flags after you fully implement the new feature.
We'll discuss both metrics and temporary flag hygiene in this section.
Metrics help us determine whether something is improving or not. Consider what metrics you need to track when you release new features.
Availability, reliability, and response time of an application should not change with the deployment of a new feature. Set up monitoring to track performance before, during, and after you deploy code to ensure performance does not degrade.
The metrics you track will vary based on your business and objectives. Tracking metrics such as page load time, errors, uptime, conversions, or user registrations can tell you whether a feature is performing well or causing problems.
Deployment and release flags should not be a permanent part of your code. After a feature is fully released and stable, you can remove all the code associated with the feature flags that support the feature. This makes your code easier to read and understand, and eliminates the possibility of accidental deactivation of the feature.
To help you know when a flag should be removed, LaunchDarkly has indicators in the dashboard indicating whether a flagged feature is fully active. An active flag has been rolled out to 100% of your userbase, so it may be safe to remove it.
To learn more, read Flag statuses.
After you decide to remove a flag from your code, you can use the Code References tab to find all the places that flag identifier appears in your code.
The removal process is even easier if you use the following practice when you add a temporary flag:
- Write the flag logic and commit your code to your repository.
- Write the code as if the flag had never existed and you had directly coded the new behavior.
Git stashthe flagless code.
- When you decide the flag is complete, commit the stashed code.
The advantage of writing this code at the same time as the flag code is that the logic will be current for you, instead of you needing to reconstruct or remember the things you were thinking at the time you wrote the feature.