How to Stop Shipping Code and Start Shipping Value!

With every deployment you do, if you wouldn’t tell your customers about it, then what was the point?

About once a week, I see someone post on LinkedIn about how fast they can push code to production. They deploy code to production 10 times a day and have the world’s most sophisticated CI/CD pipeline you have ever seen. Wow!

However… having the world’s best assembly line doesn’t mean you are building or shipping anything valuable to your users or customers.

It is better to ship something valuable to customers once a week than to ship code 10 times a day that nobody cares about!

With every deployment you do, if you wouldn’t tell your customers about it, then how important could it possibly be?

Let’s dig into the difference between shipping code and shipping value.

Can You Even Ship It?

Being able to ship code at any moment’s notice in a repeatable way is critical to the software development process.

Just last week, a friend contacted me in a panic because their software was down in production. They need to urgently change a single configuration setting and push the code update to production.

They had one major problem. The only developer who knew how to do it was in India and asleep. Lesson learned.

Setting up deployment pipelines is really easy with modern applications. I recently configured deployments of a front-end Vue app to Cloudflare and a .NET app to Azure App Services. Both only required clicking a few buttons for setting up continuous delivery upon any GitHub check-in.

At a minimum, every company needs this kind of basic, repeatable process for shipping code that anyone can do. It would have dramatically helped my friend the other day.

To take it to the next level, companies leverage various types of automated testing to make it so they can ship code with high confidence in code quality.

I love the idea of moving fast and not breaking things.

But there is still one critical question: are we moving anything meaningful?

Shipping Boulders, Rocks, and Sand

Don’t get me wrong, I’m a huge fan of shipping code fast. I hate when code sits on the shelf and isn’t deployed to production. As I type this, my SaaS company, At Capacity, has 13 pull requests backed up because of a massive project that has to be done first. I hate it.

Shipping these 13 pull requests would pad our stats. We could all weirdly be excited about how fast we closed these pull requests and how many lines of code we deployed.

However, nobody gives a shit about any of those metrics.

Our management team only wants to know when this major platform upgrade will be done. It is preventing us from signing up new customers. It’s affecting our revenues. It has significant value.

How fast we ship code doesn’t matter. What matters is how fast we ship code that brings significant new value to our users and our company.

Shipping quickly, for shipping's sake, can actually create a lot of chaos. (More about that later.)

Shipping Boulders Is Hard

This all starts with product planning. The best analogy for this is the boulders, rocks, and sand.

Every product team should plan major boulders that the team is focused on. These are the big critical projects. You can then fill the rest of the schedule with small rocks and sand to fill in the gaps.

Boulders are heavy and hard to ship. They are also the heart of the work your team is likely working on.

How often and how fast you ship code is probably spending too much time worried about moving the sand. You need to spend more time focused on the giant boulders that matter.

Code is basically nothing but bits, bytes, and, therefore, essentially sand if it doesn’t bring significant value to the customer. Don’t focus all of your delivery process on vanity metrics for small incremental shipments of sand.

Every grain of sand, or code, also takes a lot of work to deploy. You likely also aren’t considering how much effort it takes to do a deployment correctly.

Shipping Isn’t Free! A Real Deployment Ceremony is Expensive

Doing deployments the right way isn’t as simple as pushing code to the main branch and automatically deploying code to production.

Technically, it can be that simple…

In reality, the deployment process should be much more complicated for any critical software project. The bigger the company, the more complicated the deployment planning process gets.

Even if one developer is working on a project, they mentally have to think through all of these steps:

  • Planning when to do the release

  • Evaluate if proper QA/testing has been done

  • Deploy SQL or other infrastructure changes

  • Compliance & change control activities

  • Do the actual release

  • Validate the changes in production

  • Monitor application errors and performance post-release

  • Updating your work item tracking software

That is a long list of things. A small team can quickly run through all of those things in their head and decide to push code quickly. A bigger team needs to do more coordination and planning.

Even small hotfixes require some essential release planning.

If the deployment is that simple, you are likely not shipping anything of much value.

If you are shipping something valuable, you need to tell a lot of people!

  • Scheduling maintenance windows

  • Creating release notes

  • Internal training about the changes

  • Notifying customers about the changes

  • Customer Success closing support tickets fixed in the release

  • Product marketing activities

If the release is big enough, it might even be big news at the next board meeting or covered on every tech news website the next day.

If you are shipping value to your users or customers, the deployment process is more of a “ceremony” that takes time. It takes a lot of time to do it the right way.

One company I invested in did deployments every day at the end of the day. The entire development team of about 6 people spent 1-2 hours a day deploying to production and doing manual QA because they didn’t have any testing automation. 🤦‍♂️

Doing deployments daily was literally destroying their weekly productivity. It was insanity for lots of reasons. Deploying too often or using a flawed process can be a significant problem.

Death by a Thousand Updates

Imagine being in charge of marketing or customer success; every day, you are told that your dev team did a deployment to production. You have to drop what you are doing and figure out how this impacts your team and their responsibilities.

Meaningful deployments every day would be pure chaos.

Imagine working in the support department and getting bombarded by customer problems due to deployments done that day that you didn’t know anything about.

It is essential to balance the speed of shipping code with the quality of your releases. Too much focus on speed can reduce overall quality via overlooked bugs, subpar features, and poor-quality code.

It makes sense for most teams to do more significant releases less frequently and with proper communication and training. Bunch up some changes and then tell the world about all of them at once.

Sure, you can do hotfixes whenever you want. You can do releases behind feature flags. You can do releases to things that aren’t customer-facing. You can publish to QA 10 times a day.

You can’t be making significant UI changes every day.

You also can’t keep breaking things in production and creating hell for everyone else.

Shipping code isn’t just about the code. It potentially has downstream effects on every other person in the company.

Shipping is Marketing!

Sales and marketing teams are always looking for things to talk about with current or potential customers. Much of their job is just making noise to get attention.

Guess what? Every deployment is a reason to talk to customers if you are shipping value, not just shipping code.

I posted weekly social media updates at my first startup: “We released 3 new features and fixed 12 bugs…” One thing was for sure: our customers knew we were working hard, fixing things, and innovating. 

Every release is going to be a mix of hot fixes, technical debt, new features, etc. Make it a goal that every release includes SOMETHING your customers would care about. Even if it fixes annoying bugs.

You are doing it wrong if you do multiple releases in a row and have nothing to show your customers.

You have to prioritize shipping value to your customers, not just code.

Never Stop Celebrating!

There are two key takeaways I want you to think about from this post.

First, you must shift your focus from merely shipping code to thinking about the value you are shipping to customers. 

If your customers will never know about or don’t care about your work, you should spend as little time as possible on it. Why are you even doing it?

In the corporate world, it sadly seems like almost all development work is this type of work. Major rewrites of things, “technical debt” projects, pet projects that get discarded, etc. I realize it is part of the job, and sometimes it has to be done.

The key is customers don’t care. You should also care less about these projects.

I know what you are going to say: “We have to do this so we can move faster on things that matter!”. Sometimes that is true! Sometimes, you always use that excuse, too.

Try to minimize work that doesn’t deliver direct new value to customers.

Second, take time to properly celebrate your work. Every deployment is an opportunity to tell your customers how excellent your product is and how hard you work to improve it.

Every deployment is a chance to do marketing. Stop and celebrate! Toot your own horn! Have a beer!

Go ship code, but focus on shipping valuable things your customers care about. Make sure you tell them all about it.

Thank you for reading The Visionary CTO. This post is public so feel free to share it.

Join the conversation

or to participate.