In the realm of software development, the way we structure and deliver our work can significantly impact the project’s success. Enter the concept of “vertical slices.” At its core, a vertical slice refers to delivering a piece of functionality that cuts through all the layers of an application, from the user interface down to the data store. Instead of building out an entire layer of an application before moving to the next (as in traditional “horizontal” development), vertical slicing focuses on delivering small, complete pieces of functionality one at a time.
This approach contrasts sharply with the more traditional “layered” or “horizontal” development or software architectures built in layers. In horizontal development, teams might first build out the entire database layer, followed by the business logic layer, and finally the user interface. While this might sound logical, it often leads to long periods where there’s no tangible output to show to stakeholders or end-users. Vertical slicing, on the other hand, aims to deliver visible, usable features at the end of each slice, even if the application is not yet complete.
Visual Representation:
To better grasp the concept of vertical slicing, let’s use the analogy of a cake.
Okay… Maybe not that one. Although it looks delicious. Imagine a multi-layered cake, with each layer representing a different component of your software – the database, the business logic, the API, and the user interface. It can be many different layers, and it’s a lot more obvious if we cut it open with a nice thin vertical slice:
Let’s think about vertical slicing vs horizontal slicing. In a traditional “horizontal” approach, you’d be baking each layer of the cake separately. You’d start with the bottom layer, then once that’s done, move to the next, and so on. You could also have different teams working in parallel across the horizontal layers. It might be a while before you have a full cake to present.
In contrast, with vertical slicing, you’d be cutting a full slice from the top to the bottom of the cake, ensuring you get a bit of every layer. Each slice represents a complete piece of functionality, from the user’s click in the interface down to data retrieval or updates in the database. Of course, not every slice will touch all layers, but the concept of cutting across the horizontals is what’s key here. Check out this video for an intro on vertical slicing
Benefits of Vertical Slicing
Vertical slicing vs horizontal slicing can offer many benefits that can transform the way development teams operate and deliver value. Let’s delve into some of the most significant advantages:
- Faster Feedback Loop: One of the primary benefits of delivering in vertical slices is the ability to get feedback early and often. By providing a complete piece of functionality, stakeholders can see, interact with, and provide feedback on a feature much sooner than if they had to wait for all layers of that feature to be completed. This early feedback can be invaluable in ensuring the product is headed in the right direction and meeting user needs.
- Improved Collaboration: Vertical slicing naturally fosters collaboration. Since each slice involves multiple layers of the application, it requires input and expertise from various team members, be it database experts, backend developers, or frontend designers. This cross-functional collaboration ensures that everyone is on the same page and contributes to a holistic solution.
- Reducing Integration Risks: With vertical slicing, integration is a continuous process. Instead of waiting to integrate various components of a feature at the end, teams integrate as they go. This continuous integration reduces the risk of integration issues cropping up late in the development process when they can be more costly and time-consuming to address.
One important thing I would like to remind readers of is: vertical slicing is not applicable to everything, all of the time, with a perfect fit. It’s something I encourage engineering teams to strive to be able to do, but we must remain pragmatic with all things in software engineering. No silver bullets here.
Starting with User Stories For Vertical Slices
User stories play a pivotal role in defining well-structured vertical slices. A user story is a concise, simple description of a feature told from the perspective of the person who desires the capability, usually a user or customer of the system. This is in contrast to something that might be proposed by the engineering team to tackle tech debt or other infrastructure changes, for example.
Good user stories naturally lead to well-defined vertical slices because they focus on delivering value to the user. Instead of getting bogged down in technical details or specific implementation methods, user stories keep the team focused on what the user needs and why. In fact, specific technical implementation details are NOT included in user stories.
The INVEST principle is a widely recognized set of criteria that good user stories should meet:
- Independent: Each user story should be self-contained, in a way that there is no inherent dependency on another user story.
- Negotiable: While a user story provides a description of the desired functionality, the specifics of its implementation are open to discussion and negotiation between the team and stakeholders.
- Valuable: Every user story must deliver value to the end-users.
- Estimable: The team should be able to estimate the size of a user story to plan their work effectively.
- Small: User stories should be small enough to be completed in a short amount of time but large enough to provide value on their own.
- Testable: Every user story must have criteria that allow it to be tested and validated. (And you know I love talking about testing!)
By adhering to the INVEST principle, teams can ensure that their user stories are well-suited for vertical slicing, keeping the focus on delivering value in small, manageable chunks.
Breaking Down Features:
When approaching a new feature, it’s essential to think about how it can be divided into manageable vertical slices. Let’s consider a hypothetical feature: “Implementing a User Profile System” for a web application.
At first glance, this feature might seem monolithic. But when we break it down, we can identify several vertical slices:
- User Registration: Allow users to sign up with basic details.
- Profile Viewing: Allow users to view their profile.
- Profile Editing: Allow users to edit specific details on their profile.
- Profile Picture Upload: Allow users to add or change their profile picture.
- Account Deletion: Allow users to delete their accounts.
Each of these slices delivers a specific piece of functionality that provides value to the user. They can be developed, tested, and delivered independently of each other. The decomposition of the original feature into smaller vertical slices is a critical step in ensuring we have more realistic deliverables that meet the INVEST principle.
When prioritizing these slices, consider both the value they provide to the user and their complexity. For instance, “User Registration” might be prioritized first because it’s fundamental to the system and provides immediate value. On the other hand, “Profile Picture Upload” might be seen as a valuable but not essential feature and could be prioritized after the basic functionalities are in place. Check out this video for more information:
Challenges and Common Mistakes:
Vertical slicing, while beneficial, comes with its own set of challenges. Here are some common pitfalls and how to address them:
- Oversized Slices: One of the most common mistakes is creating slices that are too large. This defeats the purpose of vertical slicing, as the team won’t be able to deliver value quickly.
- Solution: Always aim to break down features into the smallest valuable components. If a slice seems too large, see if it can be divided further without losing its inherent value.
- Reminder: You won’t always get this perfect. That’s okay. Strive for continuous improvement so you can try and do better next time.
- Not Truly Vertical: Sometimes, teams might think they’re working in vertical slices, but they’re still thinking in layers. For instance, if a team works on the database layer for several sprints before moving to the business logic, they’re not truly working vertically.
- Solution: Always ensure that each slice touches all necessary layers and delivers a complete piece of functionality.
- Reminder: With more experience, this will be easier to identify. But again, this may not always work as perfectly as planned on paper. Try it out, and adjust as necessary. Learn from each attempt.
- Neglecting Dependencies: In the quest to work vertically, teams might overlook dependencies between slices, leading to integration issues later on.
- Solution: While slices should be independent, it’s essential to map out any dependencies beforehand. This ensures that the team is aware of potential integration points and can plan accordingly.
- Reminder: Keep the long-term architecture in mind as you’re delivering. You don’t need to implement it all, just ensure the general direction is being adhered to.
- Overemphasis on Speed: While vertical slicing can accelerate delivery, it shouldn’t come at the cost of quality. Rushing to deliver a slice without adequate testing or consideration can lead to issues down the line.
- Solution: Always ensure that each slice is thoroughly tested and meets the defined quality standards before it’s considered “done.”
- Reminder: INVEST! What does the T stand for? That’s right 🙂
By being aware of these challenges and proactively addressing them, teams can harness the full power of vertical slicing without falling into common traps.
Tooling and Infrastructure for Vertical Slices
Implementing vertical slices effectively often requires the right tools and infrastructure. Now like most things, there’s no one-size-fits-all perfect solution for this stuff. However, here are some that can aid the process:
Architectural Patterns Supporting Vertical Slices:
Consider how your software is architected and how it aligns with supporting vertical slices. Knowing that we want to be able to slice vertically through functional areas, how can you best support this? I have found using plugin architectures is a winning strategy here. You can use frameworks like Autofac to help dynamically wire things up, and land entire slices as dedicated plugins sometimes. I’ve had great success using this with mealcoach.io!
Feature Flags:
These allow developers to hide, enable, or disable a feature during runtime. This means a feature (or slice) can be developed and even deployed without being visible to all users. It’s especially useful for testing a slice with a subset of users before a full release. One of the great considerations here is that if you truly have created an isolated slice, with respect to your change’s impact on the surface area of the code, it should be minimal.
CI/CD Tools:
Continuous Integration and Continuous Deployment tools like Jenkins, Travis CI, and Version Control: Tools like Git help manage changes across slices, especially when multiple teams work on different slices simultaneously. Branching strategies can be employed to isolate work on a particular slice and then integrate it back into the main codebase seamlessly. While there are many opinions about feature branches and time-spent-away-from-main, the reality is when you’re doing thin vertical slices your branches should be very short-lived! Given the continuous nature of delivery in vertical slicing, manual testing can become a bottleneck. Automated testing tools, be it unit testing frameworks like xUnit or end-to-end testing tools like Selenium, ensure that each slice is robust and meets quality standards. Wire these up in your CI/CD pipeline and you’re off to the races! Tools like Docker can encapsulate a slice into a container, ensuring consistency across development, testing, and production environments. This reduces the “it works on my machine” problems and ensures smooth deployment. Vertical slicing stands as a transformative approach in software development, shifting the focus from isolated, layered development to delivering cohesive, user-centric features. By breaking down complex projects into manageable, value-driven slices, teams can ensure faster feedback, improved collaboration, and a more predictable delivery timeline. However, like any methodology, its success hinges on understanding its principles and effectively navigating its challenges. And no, not everything will feel like a perfect fit. Tools and infrastructure play a pivotal role in facilitating this approach, but the real essence lies in the mindset shift—prioritizing user value and iterative progress over monolithic perfection. For budding developers and seasoned professionals alike, embracing vertical slicing offers not just a methodological advantage but also a broader perspective on software delivery. It underscores the importance of continuous learning, adaptation, and user-centricity—principles that are foundational in today’s dynamic tech landscape. As you reflect on the insights shared in this article, consider how you can integrate vertical slicing into your projects. Whether you’re building a simple app or a complex system, the principles of delivering value slice-by-slice can guide you toward more efficient, impactful, and satisfying development outcomes. If you found this helpful, check out my weekly newsletter to have software engineering tips delivered right to your inbox!Automated Testing:
Containerization:
Vertical Slices in Summary