During my career as a software developer, I have seen the release frequency increasing steadily. When I started, it would take 12 to 18 months for new features to reach the customer. Years later the frequency increased, so deployment to production happened every three weeks. For the past two years, we have been using continuous delivery at work. This means that as soon as a feature is ready (implemented, code-reviewed and tested), it is deployed to production. Continuous delivery is by far the best way in my opinion, and here is why:
Lower risk. The number one reason I like to deploy each new feature as soon as it is done is that it lowers the risk. Every time you change the software there is a risk that bugs are introduced. If the change deployed is small, there is less code to look through in case of a problem. If you only deploy new software every three weeks, there is a lot more code that could be causing a problem. If a problem can’t be found or fixed quickly, it is also a lot easier to revert a small deploy than a large deploy.
Fresh in my mind. If I deploy a new feature as soon as it is ready, everything about it is fresh in my mind. So if there is a problem, trouble shooting is easier than if I have worked on other features in between. It is also frees up mental energy to be completely done with a feature (including deployed to production). I can concentrate on one thing at a time, instead of multitasking.
Features reach customers faster. All things being equal, the faster a feature reaches the customer, the better. Having a feature ready for production, but not deploying it, is wasteful.
Faster feedback. The sooner the customer starts using the new feature, the sooner you hear what works, what doesn’t work, and what improvements they would like. Very often, the next features to be developed is not known until the customer has tried out the current feature and provided feedback. Furthermore, as valuable as testing is, it is never as good as running new code in production. The configuration and data in the production environment will reveal problems that you would never find in testing. Therefore, the sooner it is deployed, the sooner you can find and work out remaining problems in the code.
For continuous deployment to work, there are many preconditions that have to be met. Without these, it is hard or impossible to deploy new code continuously.
Central servers. The system must be cloud based or run from central servers. If the system is run on the customer premises and under their control, it will obviously not work to deploy new versions many times a day.
DevOps culture. Continuous delivery works best when the developers creating the new features are the ones deploying them. There are no hand-offs – the same person writes the code, tests, deploys and debugs if necessary. This quote (from Werner Vogels, CTO of Amazon) sums it up perfectly: “You built it, you run it.”
Automation. When you deploy to production many times a day, deploys must be quick and easy. This means that almost all of the mechanics of building a new release and deploying it must be automated to avoid manual steps. The rest of the system must also support rapid builds and deploys. At work we use docker and kubernetes, which works very well.
Rolling upgrades. If the system is unavailable during a software deploy, you will think twice before deploying. To avoid this, the system should be set up so you can deploy new features server by server, without service interruption.
Revertible. It should be easy to go back to the previous version of the software in case there are problems with the new deploy. If it is easy to deploy a new version, then this is usually not a problem – you just use the same system to deploy the old version again.
Knowing what is running. When the software version running changes several times a day, it is important to be able to tell what it is. This means both knowing what is currently running, and knowing when changes were made. At work we use version numbers in combination with the git hashes of the software. Also, each software deploy is committed in a separate versions file.
Bugs. Some people, especially when used to scheduled releases, feel uneasy about continuous deliveries. Aren’t there more bugs as a result of these frequent releases? In my experience, no, there are not more bugs now. There were occasional bugs in the scheduled releases, and there are occasional bugs when deploying continuously. The difference now is that when there are bugs, they are easier and faster to find and remedy.
Soaking. But what about letting new features “soak” in the test environment for a while before releasing them? Doesn’t that uncover hidden bugs? This is an argument that works better in theory than in practice. Before you consider a feature done, you perform all the tests you can think of to convince yourself that it works as expected. It is possible that there are bugs that could be found in a test environment even when you aren’t looking for them, but in practice this almost never happens. Much more likely is that any remaining bugs will only be found when the feature is used in production, with real configuration, data and traffic patterns. Thus the other advantages of frequent deploys outweigh the potential of finding lurking bugs by delaying deployment.
As a developer, I want to do everything I can to make sure I create bug-free features as fast as possible. Continuous delivery is a way of working that helps in this respect. Deploying one feature at a time lowers the risk of each deploy significantly. If there is a problem, the code is fresh in my mind, and the changes compared to the previous deploy are small, so trouble shooting is much easier. In addition, it gets features to the customer faster, enabling faster feedback as well. Comparing scheduled releases to continuous delivery, I much prefer continuous delivery.