There are lots of approaches to delivering new versions of software. You can release big bundles of features all at the same time as a whole new version. Alternatively, you can release individual features one at a time, and not worry too much about version numbers. Or you can go even further by releasing features in multiple slices, iterating as you go. As with everything in software development, all of these approaches have pros and cons.
At 91导航, we favor the iteration approach - we try to slice our product work into small, vertical slices, releasing good now instead of perfect later. In this post, I鈥檒l explore why we prefer that approach, what we mean by 鈥渟mall, vertical slices鈥, and how we achieve it in practice.
Back to basics
In the beginning, software was released on physical media. The only way to deliver a new version was to batch up all the improvements you wanted to make, do a lot of testing to make sure that you didn鈥檛 have any show-stopping bugs, and release the whole new version at once. This approach is sometimes called a 鈥淏ig Bang鈥 release, and it鈥檚 still often used today for some types of software, such as games and operating systems.
There are some advantages to the Big Bang model, but there are also a lot of downsides. For example, you might spend months perfecting a whole set of features, and then discover that your customers don鈥檛 actually want that feature set, or they were imagining the features would work differently. It鈥檚 hard to set up a tight feedback cycle between your development process and the users of your product if you鈥檙e not getting new iterations in front of them very often.
In addition, it might be tricky to ship small bug fixes if your workflow isn鈥檛 set up to make releasing easy and painless. If you do a release once every six months, you鈥檙e unlikely to have spent the time and effort setting that workflow up. On the other end of the spectrum, if releasing multiple times per day is routine to your team, then getting a fix out to customers will be quick and easy.
As a result of these and other advantages, the general trend has been towards more frequent, smaller releases. This has also been driven by the rising popularity of web apps, app stores, and other distribution channels that allow for quick and easy upgrades to new versions of the software. At the same time, there鈥檚 been a trend towards using 鈥渁gile鈥 methodologies within software workflows. At 91导航 we don鈥檛 follow any particular agile methodology down to the letter, but we do pick and choose the parts we like most from a lot of them. Our approach to breaking up development work is a great example of that.
Vertical slicing
Okay, so lots of people are moving to smaller releases. Here鈥檚 where the 鈥渧ertical slicing鈥 comes in. A small release implies that not many changes are shipped in each release, but it doesn鈥檛 imply anything about the shape and nature of those changes. At 91导航, we like to think about feature work in terms of 鈥渟lices鈥.
Slices
A slice is, essentially, a single deliverable chunk of a feature. Usually a developer will take a feature that they want to build, look at what the main components of it are, and decide what the smallest useful chunk of functionality is that they can implement to get towards the goal of having the whole feature implemented.
Ideally, a slice should be a single conceptual change or, if that鈥檚 not possible, a logical grouping of changes. We avoid grouping changes when they don鈥檛 need to be grouped. Let鈥檚 say we have some alterations we want to make to a page - we want to change some of the behavior, and we also want to update the layout to be more consistent with some other pages. In this case, we鈥檇 probably deliver the work in two slices, one with the behavior change and one with the layout change, because they鈥檙e not particularly dependent on each other.
Vertical vs horizontal slices
When we come to implement a feature and start thinking about slicing, we can often think of multiple ways to break up the work. So how do we decide which way of slicing the feature is best?
Let鈥檚 take a step back to think about the benefits we鈥檙e trying to achieve. We鈥檒l explore them below in more depth, but for the moment, you鈥檒l notice that I鈥檝e split them into two sections:
Benefits of small slices:
- Limit the risk of each release - as each change is small, the risk of the release is lower
- Allow for more useful peer review - regularly reviewing smaller changes is more timely and effective
- Maintain momentum - it鈥檚 more motivating to be constantly shipping improvements
- Encourage frequent releases - smaller slices mean work gets finished more often and there鈥檚 almost always something to release
Added benefits of vertical slices:
- Deliver useful improvements to customers as soon as possible
- Get quick feedback from customers on new features
- Be able to pivot when priorities change and the thing you鈥檙e working on is no longer the most valuable thing you could be doing
- Exercise code paths and expose bugs as early as possible
Okay, but what is a vertical slice?
The term 鈥渧ertical鈥 comes from the idea of slicing down the technology stack, rather than across one layer. In general, a new feature will require some changes to all levels of abstraction.
When delivering a feature in slices, we could make just the changes to one abstraction level at a time (so, just do the database changes, and then just the backend changes, and then just the UI changes, for example). This would be a horizontal slice.
Alternatively, we could make multiple changes that sliced vertically through the stack, each adding one small part of the functionality throughout all the levels of abstraction. This would be a vertical slice.

At a glance, vertical slicing seems more complicated and difficult - isn鈥檛 it easier to just touch one level of abstraction at a time? In some cases, you鈥檇 be right. However, the problem with the horizontal approach is that the work you鈥檝e done isn鈥檛 really 鈥渞eleased鈥 in a true sense until all the layers (and so all the changes) are finished. If you do a release to change the database, and another to change the backend, none of that code will actually be executed until the UI is updated to make use of those changes. In addition, users won鈥檛 get any benefits until the final slice is in.
In contrast, with a vertical slice, you aim to release usable functionality in each slice. That way, users get their hands on the cool work you鈥檝e been doing even faster, and you get to talk to them to see if you鈥檙e taking the feature in the right direction. In addition, at any point after a slice is released, you could stop and work on something else without having any work in a limbo state where it鈥檚 released but isn鈥檛 being used yet.
This ghost-code introduced by horizontal slicing is risky in multiple ways:
- If for some reason you decide not to finish the last slice, you鈥檝e wasted all the effort in the previous slices, because you鈥檝e released no changes to functionality.
- You鈥檝e never executed that code in production, so it鈥檚 more likely that it contains unknown bugs.
- If you take too long to develop and release the last slice, assumptions made in the rest of the code may have become invalid without you noticing (again, because it鈥檚 not being executed regularly in production).
Exceptions that prove the rule
As with all rules, you shouldn鈥檛 just blindly follow the 鈥渧ertical slices are better鈥 rule. There are a few cases where horizontal slices are more appropriate.
In the main, horizontal slices are better when you have operational considerations about how to release a change to production. For example, there are cases where we need to deploy a database change independently from any code changes to make sure things are forwards/backwards compatible, as part of our blue-green deployment process. Sometimes this is unavoidable - it鈥檚 not that you wouldn鈥檛 get the benefits from vertical slices here, but sometimes other considerations make it hard or impossible to follow the rule.
You might be able to get the best of both worlds by slicing each of your vertical slices horizontally to increase your granularity (in the diagram above you鈥檇 end up with a release 1a, 1b, 1c etc.) Whether that approach ends up with overcomplication and slicing your releases too small is something of a judgement call.
As usual with this sort of rule of thumb, life doesn鈥檛 always fit neatly into the analogy. You won鈥檛 always be able to categorize your slice neatly into 鈥渧ertical鈥 or 鈥渉orizontal鈥, and there isn鈥檛 always a clear best way. It is, however, a useful framework for thinking about how to split up large chunks of work, and an idea that we have found very powerful at 91导航.
