Deciding how and when to ship a new feature can be a sensitive topic. Nobody wants to break production and upset customers. And still, deploying to production tens to hundreds of times a day has become common for a lot of companies. In this post, I want to explore how shipping early and shipping often can radically improve your team's velocity while reducing the risks associated with delaying releases to the point of having to ship an uncomfortably high amount of work at once.
I will split this up into the two leading principles: Shipping Early and Shipping Often.
🌄 Ship Early
Best applied to features that can be broken down into multiple smaller deliverables, shipping early helps you iterate faster by releasing smaller chunks of work with less overhead, compared to waiting for the complete feature to be done and then pushing it out all at once.
It is important to see this not as an absolute rule but rather as a guideline for cases when it's possible to push out pieces of work once they're done. In a few cases, you'll have to complete the full feature first for it to make sense, but often you're able to ship some prerequisites early on, which will reduce some of the complexity later on.
This does not mean, however, to release without thorough testing or quality assurance, as sacrificing quality for velocity should not be the goal here. We want to move fast to distribute complexity more evenly compared to developing a huge buildup of changes that have to be pushed out all at once.
We also do not want to ship when any concepts are still subject to change. Having to pull back already released work due to a change of mind should happen as rarely as possible. Ideally, handoff to the engineering team will take place only once all preparation work in terms of planning and specification is completed. This should prevent development inefficiencies arising due to a change in expectations.
Another hugely significant tool that can be used here, are feature toggles: Being in control is key to managing feature rollout. While a few features may require to be released at once or not at all, it is often preferable to coordinate incremental releases, so you remain in control and can terminate rollout early if you're running into problems.
Feature toggles also help to prevent any service interruptions in case a migration is still necessary. What's more, if you need to disable a feature running in production due to maintenance or bug investigations, it's easy to flip the switch if you built that logic in early on.
To conclude, breaking down units of work into deliverable pieces that are rolled out incrementally enables you to iterate and ship frequently.
🚀 Ship Often
As we learned above, shipping self-contained chunks of work early can reduce some of the pressure of rolling out changes. Iteration would not be possible without a certain velocity of deploying, so shipping often becomes a requirement.
Going through multiple stages of review, approval, and testing in staging environments, deployment workflows have a high impact on how straightforward it is to ship a change from development to production.
While enforcing quality assurance by the means of performing code reviews, automating testing flows, and running other essential continuous integration tasks is crucial to avoid regressions and bug-related incidents, the complete process of shipping should involve as little friction as possible so going from submitting work for review to it running in production should be a matter of minutes or hours instead of days or weeks.
Piling up unreleased changes inevitably slows down operations, too: The complexity of finally rolling out those changes grows with every item added to this batch, where every change might require a migration to be run and monitored. Stale work might have to be brought up to date repeatedly, taking up valuable resources. It gets even worse when time is running out and you have to fight the clock to meet deadlines.
While it might require some upfront investment in optimizing release flows and tooling, the benefits of having the ability to ship often clearly outweigh those initial costs.
At this point, the reduced overhead and gained velocity in shipping features requested by customers will become the greatest asset of product development and sales, and by that, your business.
Shipping Early and Shipping Often is a set of principles that help your team to move faster by increasing deployment throughput while maintaining confidence and staying in control of feature rollouts.
It doesn't mean that you should ship broken or untested code, or ship features when they're likely to change, but rather that these simple measures can help you distribute complexity and enable iteration.
I hope you enjoyed this post! If you've got any questions, suggestions, or feedback in general, don't hesitate to reach out on Twitter or by mail.