Handling dependencies efficiently
In large organizations, the complexity of planning is often staggering. By giving dependencies the right amount of focus, you can reduce wait times for higher productivity, reduce risk for higher predictability and increase flexibility for lower time-to-market.
An operational approach to dependencies
This 3-step approach can be used no matter if the dependency is within the team, across the organization or external.
Identify dependencies
If you have an event like the PI Planning, this is a great place for teams to identify dependencies. It is, however, just as important that you have a process for identifying dependencies during the iteration. Usually, I add newly identified dependencies to the Program Board and adjust the plan as needed at the upcoming Scrum-of-Scrum.
Reduce dependencies
Not all dependencies are equally complex, but we want to avoid a situation where “everything is dependent on everything”. Contrary to many beliefs, this is actually seldom the case. Instead, ask yourself these two questions and adjust the dependency accordingly,
- Which part of this feature is blocking the other feature?
- Which team is dependent on whom?
Handle dependencies
Once you have identified and reduced the dependencies, use this prioritized list of solutions to handle them.
- Include all related work in one team for daily coordination.
- Postpone the blocked feature until the dependency has been resolved.
- Make a design agreement (e.g. a database utilized by multiple features or an interface between multiple features). If it, at any point, needs to be updated, inform the other teams.
- Formulate an enabler describing the exact dependency and have the receiving team write the acceptance criteria. If the developing team experiences a delay - or the receiving team does not need the enabler until later - the other team is informed for full transparency.
- If everything actually is dependent on everything, establish an extraordinary Scrum-of-Scrum session for the people involved from all teams to adjust the plan on a daily basis.
Using enablers wisely
Traditionally, organizations built all of their databases, servers and backends prior to delivering any value. However, as customers’ needs change over time and technology evolves at a high pace, this often resulted in more complex solutions than were actually necessary. At the introduction of user stories, the focus shifted to the other extreme - only talking about business value. Although this is better, it quickly meant that a lot of technical debt was being introduced resulting in frail solutions. By using enablers, we can balance out these two extremes.
When to use enablers
I see way too many enablers in most organizations. As a default, you should include all the technical foundation required for the feature to bring value in the feature. There are, however, three cases where enablers are recommended:
- To implement a database or an interface in order to remove dependencies (#3 from above)
- To enable another team to finish their feature in order to stay aligned on the minimum needs (#4 from above)
- To show actual progress in every sprint if a feature simply cannot be broken down in valuable user stories.
The common anti-patterns
Often, even though the intentions are good, a specific solution that initially seems nice, might have some negative consequences below the surface. Let me go through a few of these.
Dependency-driven prioritization
In the below example, the blue table describes the standard view on how to prioritize without looking at the dependencies. What is often done when you identify the dependency is the red table, where the order is completely driven by the dependency and $20 is spent with little value gained.
Instead, we want to acknowledge that A will not have any value without C, meaning the cost of A is actually not right. Therefore, include C in A - or at least the part required to achieve A - meaning the priority might actually look like the green table.
If you have many cases like this, it is an indication of your features not being sliced in an optimal way.
Enablers are must-have
A weird, new trend is that developers argue that an enabler is must-have because it is an enabler. But even though enablers are not directly connected to business value, they should still be driven by business value. Thus, developers should be able to articulate exactly which part of which feature is not possible without this enabler, such that the business can determine if they still want that feature.
Designated area of expertise
The mindset of many organizations is that we must utilize the team competencies in the best way possible. This is not ideal as the customers at some point might not need something that requires these exact competencies. Furthermore, it goes against a culture of collective ownership as every team will only chip in on their designated area of expertise. This again will force more dependencies and complexity in the plan than what is actually needed. Instead, optimize for finishing the most valuable feature in the shortest lead time possible.
Stop starting, start finishing
By far the easiest way to reduce complexity is to have less work in progress. Achieve this through WIP-limits or by introducing pull in your kanban systems, meaning most work will either not be started or is already done, thus the work is static in a system context. Additionally, establish a prioritized backlog. Thereby, the dependency will no longer go both ways, but merely be handled within the highest priority, thus making the lower priority smaller in size, as you only need to implement the remaining work.