The Art of the Vertical Slice

Agility means taking a small step and then seeing where you are. That requires cross-functional teams to work in vertical slices.

Jason Godesky
Better Programming

--

An illustration of a slice of rainbow cake composed of several layers, each with its own color.
Any article on vertical slices is required to use the metaphor of a cake. (Credit; 588ku)

In both of my last two stories, I talked about this algorithm for agility that Dave Thomas offered in his talk, “Agile is Dead”:

  1. Figure out where you are.
  2. Take a small step towards your goal.
  3. Adjust your understanding based on what you learned.
  4. Go to step 1.

This seems really simple (and it really is), but there are quite a few crucial assumptions baked into it, and it’s those assumptions that we most often trip over. One of the biggest is that, in order to do this, you need a team that is capable of taking a small step.

For example, I was once responsible for implementing Scrum with a UX team. There’s a pretty big complication here: a UX team can’t take a step by itself. We made lots of designs, sure, but a design alone won’t help you learn anything, so there’s no adjusting our understanding and no feedback loop. We got around this by using the tools of UX itself (UX research allows us to check in with our end users; sprint reviews allow us to check in with our stakeholders; and retros allow us to check in with ourselves), but let’s be real — our mockups aren’t always exactly what makes it out into production, and users don’t always use prototypes exactly the same way as they use real products out in the world. We did what we could by focusing on keeping our feedback loops intact, but a UX team can’t really be agile for the same reason that a QA team or a team of software developers can’t really be agile: because the team needs to be capable of taking a step by itself, without depending on another team to complete the work. If you have a UX team that hands designs off to a development team, a development team who hands an environment off to a QA team, a QA team that approves those environments, and scheduled releases, and they’re all following two-week sprints, then you don’t have two week sprints, you have (at minimum) six-week sprints, because that’s how long it takes to go from an idea to something in production that users are using and that you can observe and learn from.

To take a step (small or otherwise), a team needs to be cross-functional. A UX team is not cross-functional. A team of developers is not cross-functional. A QA team is not cross-functional. A team made up of a UX designer, a software developer, and a QA specialist might be cross-functional, if that covers everything that goes into taking a step. Only cross-functional teams can be agile, because only cross-functional teams can take steps on their own, so only they can complete the iterative cycle of adaptation and inspection. I should note that this is an explicit requirement in the Scrum Guide: “Scrum Teams are cross-functional, meaning the members have all the skills necessary to create value each Sprint.” Notably, “[w]hile implementing only parts of Scrum is possible, the result is not Scrum,” so that mandate I mentioned before — to implement Scrum with a UX team — was actually impossible. That’s why, even after leaning heavily on the benefits of UX research itself to create some feedback loops that we could control ourselves, we still had only limited success.

Once you have a cross-functional team, you can start making small steps. How small is “small”? That’s up to the team. You want to make these cycles as quick as possible. If you’re following Scrum, you’re limited by how often your stakeholders can meet. If they can only meet every other week, then you’re working in two-week sprints. That means you need to identify what fully-functional slice of value your team could deliver in two weeks. That means all the steps you consider crucial for maintaining quality: architected, designed, implemented, merged into the main trunk, all tests passing, approved by QA, deployed to production, validated with user research, and any other checks or processes that are important.

UX professionals often complain, “I can see where this works great for engineers, but it just doesn’t work for design. We need time to conduct research, to ideate, to really dig into how we’re going to create a solution. You just can’t do that in a two-week sprint.”

Software architects often complain, “I can see where this works great for developers, but it just doesn’t work for software architecture. We need time to plan out how all the pieces fit together, to really understand the requirements and how best to solve all of these problems. You just can’t do that in a two-week sprint.”

Developers often complain, “I can see where this works great for software architects or UX designers, but it just doesn’t work for software development. We need to create our data layer, and then our entities layer, and then our use cases layer, and then our controllers layer. You just can’t do that in a two-week sprint.”

If you’re thinking that this is easy for someone else, but won’t work for you, allow me to disabuse you of that notion. This isn’t easy for any of us. We’ve all been trained to work within the confines of a heavily-specialized cascade, in which we receive work from someone and hand it off to someone else. A waterfall, if you will. This is Big Design Up-Front (BDUF), and while it can work great for simple problems, or when we have perfect knowledge of all things (including the future), the only problems we really deal with in product development as a practical matter are at least complicated, and most of them are complex. For these problems, BDUF just doesn’t work. By the time your work has tumbled all the way down the waterfall, the situation has changed. It’s a great way to produce solutions to last week’s (or last year’s) problems. To solve today’s problems takes a more agile approach. There’s a learning curve in that for everyone. We all have to reevaluate how we work and why. That’s one of the things we all have in common here.

The key is to start taking an evolutionary view — one in which we work in vertical slices. These are the “small steps” we’ve been after. It’s not a work item, like conducting a user interview, completing a mockup, adding a new database table, or writing a new class. It’s the way all of those things (and more) come together to make something happen for a user. It doesn’t have to be big (that’s what makes them small steps). A vertical slice can be displaying a landing page, or changing the text size, or being able to log in with an email address and password, or sending a notification to your phone when something happens. It doesn’t have to be big or complex — in fact, it’s better if it’s not.

If it’s more than your team can complete in a single iteration of your feedback loop, look for ways to break it down into smaller slices. Don’t think of it in terms of the work you have to do or how you’ll approach it; rather, think of it in terms of how someone will use it. With the login example, I specifically said login with an email address and password — logging in with a third-party OAuth 2.0 service would be a separate slice, as would registering in the first place. The error messages you receive when your authentication fails, on the other hand, would be part of that slice, because it’s not fully working without that.

User stories are fantastic tools for helping us make vertical slices, but like Scrum, they have been horribly abused, and it’s very likely that what you’ve encountered as “user stories” fundamentally violated the original point of the practice. Kent Beck explained:

What I was thinking of was the way users sometimes tell stories about the cool new things the software they use does: “I type in the zip code and it automatically fills in the city and state without me having to touch a button!” I think that was the example that triggered the idea. If you can tell stories about what the software does and generate energy and interest and a vision in your listener’s mind, then why not tell stories before the software does it?

It was shortly after this that Alistair Cockburn said that:

A user story is a promise for a conversation.

There are a few key points to notice, just from these pithy snippets:

  • A user story has a protagonist: a real person who’s going to use the product we’re developing. Internal users exist, but they’re always people. The day you write “As a system” at the start of a user story, all is lost. It won’t be long before all of your user stories begin like that, with nary a red-blooded human being to be found. When your protagonist becomes a “system,” you’re writing horizontal layers, not vertical slices. If we can say “As a system,” then we can write stories in terms of layers, the way it makes sense to us when we’re writing code. We don’t have to do this hard work of thinking about our users anymore! But it’s that human protagonist that keeps us focused on a full vertical slice, because it keeps us focused on what value we’re trying to deliver for that user. It’s that focus that ensures that we’re developing the right thing, and not just a bunch of complexity that no one will ever use.
  • A user story is an invitation to customer collaboration. (Oh, hey, doesn’t the Manifesto for Agile Software Development say something about that?) It’s an invitation to collaborate with the team’s immediate customers, who might be product managers or business leaders, but it can (and should!) also be an invitation to collaborate with your ultimate customers: those red-blooded human beings who are the story’s protagonist, who will end up actually using this thing you’re making.
  • A user story isn’t a contract. If it comes to you with a mockup and acceptance criteria, it’s not a user story, it’s just a tiny specification for a tiny waterfall dressed up in a fun outfit. We work with user stories to keep us focused on who we’re making this for, and what we’re making for them. Figuring out the details of how to do that is the work. We work in cross-functional teams so that we can deliver the whole package, however small the increment may be.

Of course, if you insist on replicating the compartmentalized layers of the old waterfalls, this method will introduce more waste than anything else. If the UX designer works alone on Monday and Tuesday to make some mockups while everyone else waits, and then the developers code it up on Wednesday, Thursday, and Friday while everyone else waits, and then the QA team goes over it early the following week while everyone else waits, no one’s going to have a good time. On the other hand, if you take the principles of mob programming and expand that to the rest of your cross-functional team, you have the opportunity to achieve something amazing.

When I say that, I can feel everyone looking at the other group with “Well sure, that could work for me, but that would never work for you” written all over your face, so allow me to dispel some misconceptions.

It’s true that I haven’t heard much about “mob design” before (though that doesn’t necessarily mean that no one is doing it). Pair designing is definitely a thing, though, so if mob programming is such an improvement over pair programming, why not mob designing? Moreover, the best designers of digital products have already figured out the transformative power of pairing with their developer colleagues. We know that this is a formula for great design — so why should it be such a revolutionary idea to invite designers to join our mobs?

The most common objection to mob programming is that it’s a waste of resources. If you have one developer typing, and three others looking at the screen, aren’t you paying four developers for the output of one? This mistakes the work of software development for typing. The typing is not the bottleneck in software development; thinking is. Human beings think better together. We understand this quite well in other contexts, so why is it such a radical notion when we apply it to software development? Peer reviews and pull requests can be eliminated, not by compromising code quality, but by increasing it. Mob programming isn’t paying four developers for the output of one; it’s paying four developers for the output of five.

By involving them in the mob from the start, QA specialists make sure that quality is something the mob focuses on throughout the process, rather than making it a box to check off at the end. Your mob might take one user story through mob designing, mob programming, and mob testing, and different team members might alternate between leading and support roles as you do, but it’s the involvement of the entire cross-functional team in each step that ensures the high-quality increment that it ultimately produces — with fewer bugs, less rework, and higher standards of quality.

Approaching work in vertical slices is a foundational skill for writing good user stories. It’s a foundation that allows you to approach product development in a new, more agile, more productive way, but it doesn’t come naturally to any of us. We’ve all been trained to play our parts in the waterfall, and even the ubiquity of Scrum hasn’t really changed that. We’ve just adopted Scrum cargo cults that obsess over story points and velocity instead of phase-gates and hand out different labels and titles, but otherwise keep the old ways of working intact. Change is hard, but if the way you’re working isn’t accomplishing what you want, it’s necessary.

Learning to think in terms of vertical slices instead of layers isn’t easy, but it’s a necessary first step towards a healthy product development mindset. The alternative, where we lay out a big, perfect plan for the project and then hand it to the next team in the queue only works if we’re omniscient. For human beings limited to existence inside of a linear experience of time, it’s not possible to know what the right solution will be for the problems that our users will have next year when we’ll be ready to launch our big product. We can only know what problems our users have right now, and try to give them something right away, even if it’s small. We can keep building on that, evolving a solution over time that adapts as our users’ needs change. That’s the sort of thing you create when you’ve completed enough vertical slices. It may not be perfect, but it sure beats a detailed specification for a solution to last year’s problem.

--

--

I’m a product designer with full-stack development experience from Pittsburgh, Pennsylvania.