on deployments

You need to deploy software all the time. That's my believe, and here's why. Let's start at the beginning, though.

What is a deployment? For the discussion here it's basically the process of moving code from wherever it is to production. For software that means that hypothetical value turns into real value exactly at that point. It's when the Pizza gets delivered. All the activities before going to production are really pointless unless you actually roll something out.

Of course, production deployments are also a little scary. Deploying broken code might lead to the exact opposite of the intended effect and actually take value away from users, so exercising some caution is probably a good idea.

But a lot of organisations are outright scared when it comes to moving stuff to prod. Not concerned, not cautious - they dread doing it. And consequentially, a few things can happen, and all of them are not great – that's where I'm holding my strong opinion.

The first thing to go when you're scared shitless of deploying something is frequency. On some of the most critical things I've worked on, we deployed almost daily, and no one would be concerned about that. Moving fast allowed us to ship small increments with a boring regularity. We'd sometimes watch a bit more careful if a bigger change went live, but overall, it was just an eventless low-key stream of deployments that made sure we wouldn't sit too long on bug fixes, valuable improvements or anything else that we've been working on. If you stop doing regular deployments, you also stop deploying small things and rather move to deploying bigger change sets at the same time. This in turn also increases the risk of something in that change set breaking, so in an order to avoid stuff going wrong, you actually introduce more risk. So keep deployments very, very frequent. The smaller the units that get deployed, the more regularly code gets pushed out, the better.

The second thing that I've observed happening is the establishment of all sorts of approvals, checks or other red tape that makes sure a deployment has to go through a certain process before it can go live. And that can be as low-key as only a select group of people being able to actually approve a deployment or selected folks having to manually start a job to run the deployment itself. What that does is introduce a barrier to actually moving fast. Now you need to build something and convince the gatekeepers that something is safe. The thing here is - if something is not safe, or not tested, or doesn't adhere to the quality standards of the team, how did it make it way into the codebase in the first place? This is fixing the wrong problem - the right problem here is to make sure that all code that gets merged to mainline is fit to be released to production at any point in time. If you cannot trust that whatever is floating around your mainline can move to production, then that's a great problem to solve. Additional approvals are not.

The third thing is that deployments become a thing in itself. Deployments should ideally be happening regularly, triggered by anyone working on a team to ensure value makes its way to your users as fast as possible. The slower you make that process, the more gates and barriers you introduce, the more the boring deployment will turn into an event itself. When working at Adidas, I was entirely clueless when the last deployment happened, simply because we had them all the time. The antithesis to that is having deployments as a celebration. That comes with a fixed timeline, a bunch of performative tasks that add little to no value and, as a cherry on top, alignment meetings to align on a deployment. All in the name of making sure we're not doing anything reckless, but with the purpose of making it really hard, slow and rare to have things move to production.

What I feel is super important to speak about is the difference between Releasing something, and Deploying something. Deploying, for me, refers to the process of making technical changes available on the production or live environment. It's a purely technical thing, that doesn't necessarily come with any changes for the end users. I'm sure Google releases a new version of their search page all the time, I just never notice – it has little impact for me. Releases, on the other hand, are something that is very user visible - might be a new feature, an iteration on an existing one or any other user visible change. I don't like to mix the two up - while usually deployments contain the necessary changes to release something new, there's tools that allow the controlled rollout of new features independent of the technical deployment - things like feature flags, that allow the selective management of feature availability independent of the code that's deployed.

Coming back to my strong opinion, the goal needs to be that everyone in your team can trigger a deployment pretty much any time they feel a change is completed and merged to the mainline. You should have a way of ensuring, automatically, that new code doesn't mess things up. You should have a way to make sure a new deployment doesn't blow things up - again, automatically. Your team should know how to roll something back if a deployment didn't work (that happens, and shouldn't be a big deal).

There's so much more value in enabling all of the above - and with that a direct line between feature development and value creation for your users than making it super hard, awkward and expensive to getting code shipped in the first place.

Don't get good at solving the wrong problem, solve the right ones. And then: ship it.