Beliefs on Technical Ownership
Belief 1—Cognitive Load
There is a misconception that creating a constrained working environment or putting boundaries of control on pieces of the solution or product will reduce cognitive load. A similar misconception is that the span of control for managers is connected to the number of direct reports, leading to an overload of hierarchical layers and reporting structures. Product engineers do not appreciate the latter, yet limited or localized “ownership” is quite popular.
We consider this belief to be a myth rooted in a context of local optimization and narrow views. Let’s delve deeper into the context of narrow-scope ownership for teams.
An organization with a long-term focus and teams with ownership of components and value streams has a lower ability to focus on the most important elements; this is simply because not all components and value streams have equal priority simultaneously. If an organization does focus on the most important aspect, then teams in charge of components that don’t require much change or maintenance at one point in time would have nothing to do. This clearly doesn’t happen since nobody finds it acceptable to have idle teams. Therefore, the organization also ensures that nobody is idle by introducing initiatives/projects/work that keep everyone busy.
Although it may seem that cognitive load should be relatively low within teams, the reality at the company level is more complex. Company objectives often require the participation of multiple teams, but this involvement isn't always steady or continuous. For example, if my team is deeply involved in one initiative during an iteration, we might pause our efforts in the next iteration due to dependencies on another team. While waiting for our next active phase in the project, we keep busy by taking on different, unrelated projects to avoid downtime. Switching contexts between different projects results in a higher cognitive load, as team members must juggle multiple tasks and priorities simultaneously.
We often see even more challenging situations. Each team's product backlog is crowded with competing requests from multiple projects. Product owners are swamped with managing stakeholders, each with their own roadmaps and deadlines. Instead of focusing on a single task during a sprint, teams must work on requests from various projects. This leads to a significant increase in cognitive load. To cope, teams start an iteration by dividing and assigning tasks among individual members to reduce overload. Additionally, they often skip meetings with stakeholders, users, and customers because there are too many participants, and these meetings are generally focused only on progress updates. Overwhelmed by the complexity, teams may narrow their responsibilities to avoid being spread too thin, inadvertently distancing themselves from the broader product goals and direct customer interaction. This shift toward a more technical focus moves them away from understanding and addressing the full scope of customer needs and inter-team collaboration.
At some point, management sees a “resourcing” issue. Projects claim to lack capacity despite the many staff in component teams. As a solution, they begin to move people between teams or create fractional engineers (a single person who dedicated a percentage of their capacity to a single team), which increases people's cognitive load even further.
Simply put, due to organizational dynamics and needs, the more a team focuses on its (set of) components or value streams, the less actual work focus it will have.
Alternatively, teams with end-to-end (e2e) responsibility who work across components with a whole-product focus will have much better focus. This is because they have fewer (harmful) dependencies on other teams and fewer simultaneous projects (as there is no need to simultaneously start many initiatives simply to keep all teams engaged in something). There’s more on this in the next chapters.
Belief 2—Daniel Pink’s Autonomy, Mastery & Purpose
For many, the concept of ownership is closely linked to Daniel Pink’s ideas around intrinsic motivation—he believes it is driven by autonomy, mastery, and purpose. Let’s explore each element in more depth.
Ownership allows one to take pride in their work, much like the pride one might feel in owning a tangible asset like a house, a car, or a watch. The aspect of ownership that resonates with us most strongly is autonomy, as having control within the defined boundaries of one’s responsibilities simplifies decision-making processes significantly. Yet, involving multiple people boosts quality in decision-making because diverse perspectives are represented. Each person adds unique insights, experiences, and expertise, which helps in identifying blind spots and considering different angles. A decision is only as good as the perspectives it considers. So, while having fewer people involved may make the decision-making process easier, the quality of the decision made is questionable as diverse perspectives are lacking.
Are we saying autonomy should be compromised in favor of collaborative decision-making? No—quite the opposite. Each team should have very high autonomy to fully solve a customer problem. During this process, the team makes many decisions independently, and since they are operating from a whole product focus, they may also decide to sync with other teams to facilitate cohesion, consistency, standardization, etc.
Mastery, another key component, involves expanding one’s expertise and skills to the edge of one’s current knowledge. However, if the boundaries of ownership are too narrow, it can stifle the opportunity to expand this expertise. Broadening ownership, conversely, could pose challenges but also offer richer opportunities for growth. We have personally experienced significant growth by pushing beyond our immediate circle and incorporating insights and ideas from people outside our core domain. These interactions often lead to unexpected discoveries and innovations, which might not occur if ownership is too restricted.
Lastly, the concept of purpose extends beyond mere ownership of a certain technical implementation. Ideally, everyone aims to impact customers' lives meaningfully and positively influence the business landscape. The ultimate goal should align with broader, more impactful outcomes rather than just holding the reins on a small solution segment.
Belief 3—Conway’s Law
As mentioned previously, Conway's Law explains how cross-group communication influences the systems they create.
Many organizations suffer from architectural mess and mismatch with the business/customer domain perspective. Conway’s Law is seen as an insightful means of resolving the problem. First, alignment between the customer domain and architectural structure (domain-driven design, DDD) is established. Domain-driven design practice often plays an important role in creating so-called bounded contexts. The domain is split into loosely coupled parts, which form bounded contexts. These contexts act as starting points for the formation of independent components or microservices and are intended to assist in aligning technical and business perspectives.
Up to this point, we see no important issues relating to explained reasoning. DDD and alignment between the customer domain and architectural structure are good practices. From this point, many assume that Conway’s Law is unavoidable. Therefore, teams are structured according to separation in architecture. Each team owns one or multiple components or microservices according to bounded contexts. Due to proper alignment, the assumption is that business or customer requests will be limited to one team. Each team is customer-centric and can solve customer problems end-to-end. Such teams are often called “value stream teams,” “value stream aligned teams,” or “product teams”. The fundamental problem in this reasoning is that
-
The customer domain and architectural structure are static in nature, with changes over time.
-
Customer needs and corresponding requirements are orthogonal and very dynamic; they don’t necessarily fit into one small part of the domain owned by a single team.
We will explore the consequences of these aspects later.
It is important to note that aligning organizational structure with a solution architecture can have several consequences:
-
Static Architecture: Organizations tend to assume that the initial architecture will remain unchanged in the long term. Any alterations in architecture would then necessitate corresponding changes in organizational structure. This leads to a cumbersome process of analysis, decision-making, and potential restructuring. However, this approach disregards the concept of evolving architectures advocated in Agile methodologies. It also disregards the important practices of always starting with a simple, “just enough” architecture (YAGNI - You Ain’t Gonna Need It). In other words, generally, we should avoid building microservices from scratch. Instead, we should evolve into a distributed architecture from a simpler monolith.
-
Early Decision-Making: It’s assumed that all necessary information required to make significant architectural and organizational decisions is available upfront. Real Options theory suggests that delaying decisions until more information is gathered often leads to better outcomes. Hence, early decision-making leads to suboptimal decisions.
-
Ownership and Policing: Assigning ownership of different parts of the solution will lead to a hierarchical structure in which others must oversee the entire solution, meaning policing will be required to ensure alignment with overall goals. This imposes external rules, guidelines, and approvals, increasing the cognitive load on teams. It also leads to a more complex organizational structure due to the additional roles required (architectural, business analysis, and testing). The teams cannot oversee the entire solution due to their limited scope of concern.
-
Unequal Importance: Not all components are equally important in delivering business value at any time. Because teams will not wait until work in their component becomes important, they will work on something else. In other words, teams optimize for utilization. This leads to context switching between various projects and tasks, significantly increasing cognitive load and potentially impacting productivity, as mentioned before.
Even if one overcomes architectural issues somehow, the ability to fit customer/business needs within the scope of a single team and the corresponding small section of the architecture depends heavily on the level of decoupling between different parts. The parts would have to be heavily independent. It is hard to imagine a customer product disintegrated and split into (very small) constituent parts spread among teams. As an example, Amazon AWS services used to be developed almost entirely independently from each other, but this is no longer the case. Disintegrated or completely decoupled architectures are very rare because the value of a customer product is, for large part, defined by the level of integration between capabilities of that product. In other words, stronger integration means more potential customer value.
This means that separation between bounded contexts is limited. Therefore, a customer request will cross that boundary, requiring multiple teams to implement a feature. If component ownership is not shared, this will lead to dependencies between teams. And, as mentioned above, the nature of customer needs or requested features is highly dynamic (doesn’t follow a fixed structure), while the nature of the customer domain is rather static (the structure is stable).
Any feature that crosses the boundary will take significantly longer to deliver due to dependencies, integration, and end-to-end testing of the whole feature.
In addition to that problem, domains contain shared parts. For example, the consumer banking domain usually has core banking as a shared component. Significant shared components will mean that separation between bounded contexts is non-existent. In other words, multiple teams depend on the same component. If strict per-team ownership is maintained, then the organization will inevitably create a component team that manages that shared component: a core banking team. This means that the core banking team will be a component team, and all customer-facing teams will depend on that component.
This situation will heavily impact overall agility if changes in core banking are frequent. The original idea of applying Conway’s Law was to reduce cognitive load by splitting the ownership of components between teams. Ironically, due to dependencies, teams will need to pay significant attention to managing dependencies between them. This means increased cognitive load due to context switching between building features and reacting to the consequences of inter-team dependence.
To soften the impact, groups introduce several practices:
-
Contract testing—validating components separately using the other components’ agreed contract and/or API (application programming interface).
-
Communication between teams through APIs—the idea is that teams don’t need to communicate or coordinate across teams much; they just use the documented API or request a change to the API when required.
Again, this thinking overlooks the complex reality of API design and its usage. The approach makes sense and works if:
-
The API is simple and standardized. We can use the analogy of an EU power plug with 220 volts versus USB-C. The first one is simple and standardized, while the second one is less so, and there will, of course, be related consequences. The interface fits, but it may or may not transmit data by knowing only the interface.
-
API is stable. This means it doesn’t change often.
As mentioned before (by Conway in his paper and by us in relation to the inverse Conway maneuver, one of the essential aspects of agility is the ability to evolve or adapt architecture. This means that improvements in API design should be embraced, leading to API changes. Such improvements result in a high cognitive load on teams when managing, testing, and monitoring API changes across many teams. Particularly painful ones we have observed include:
-
Discovering which component is causing an issue in production.
-
Overall performance issues due to a chain of requests between many components.
-
The necessity to have a very complex test environment across all components since contract testing proves insufficient.
-
Maintenance of multiple versions of the same service.
This brings us back to the conclusion of Conway’s paper: that organizations need to be highly able to change architecture and team structure according to evolving insights. As we now know, such an ability would introduce a high cognitive load to teams; they would constantly need to realign with other teams due to changes in integration across components and corresponding APIs. Since such changes are very expensive (they impact multiple teams and require end-to-end testing, versioning, etc.), product groups generally avoid them. Instead, teams seek workarounds:
-
Instead of a proper API design change elsewhere, teams implement wrappers or business logic in their components since it is much easier, especially with deadline pressures. This leads to duplication and a general architectural mess.
-
Teams continue to create new components (microservices) instead of improving existing ones, creating an even bigger mess.
Referring to a specific example, a company had a special role called “sheriff.” Multiple people with a full-time role would chase teams to fix their failing microservices/components in the testing environment. At any point, at least one service seemed to always not work as expected when its API was used.
When looking at this problem over a longer period of time, we observe that one of the major root causes of high team cognitive load is the architectural mess caused by the above dynamic. The architectural mess and its complexity becomes too much to handle, so organizations limit the scope of responsibility and ownership of each team. This leads to more mess, which leads to a further reduction of scope, among other things. In systems thinking (or modeling), we call this a reinforcing loop.
The architectural mess is further exacerbated by the fact that teams don’t have the incentive to remove components they work on since their existence depends on the existence of those components.
Conway’s Law is Avoidable
Organizations that apply systems thinking (we know many) and come to understand the above harmful dynamic are able to reverse it and reduce teams’ cognitive load by:
-
Gradually increasing shared ownership.
-
Reducing the hard link between the structure of teams and the architecture they work on.
-
Establishing strong collaboration between teams.
-
Expanding the scope of concern per team, which increasingly overlaps with other teams.
-
Having an active architectural community consisting of team members focused on simplifying the overall architecture.
-
Shifting specialization from components or services toward parts of a customer domain.
-
Improving the architectural/design and testing skills of teams.
Many organizations have overcome Conway’s Law and reduced the cognitive load on teams. This seems to defy logic since common sense tells us that shared responsibility and collaboration across teams must lead to a higher cognitive load. However, this common sense becomes mistaken when we understand the explained dynamic and apply systems thinking.
Belief 4—Technical ownership leads to higher quality
Regarding the myth that technical ownership is necessary for maintaining quality architectures and avoiding unmanageable monoliths, it's essential to consider alternative practices. Teams can maintain quality through small, iterative changes, test-driven development (TDD), robust code linting, continuous integration (CI) with static code reviews, and other techniques. Many successful teams we work with that have abandoned per-team technical ownership rely on these practices and receive rapid feedback, resulting in manageable codebases without necessarily resorting to monolithic structures. We have seen developers overwhelmed with 10 thousand lines of code, while others work with 10 million lines without overload.
Practical tips for a gradual increase of shared ownership include:
-
Execute “component readiness for sharing” assessments for each component (testing automation, code quality, and deviation from the standard tech stack).
-
Assess and improve technical capability/skills per team (tidy code, refactoring, CI, dealing with legacy, specification by example, etc.).
-
Increase shared ownership per team and per component and only when needed.
-
Establish component mentors that teach, assist, and review code when needed.
-
Execute component sharing in stages:
-
The source code can be seen but changes are done by a more knowledgeable team.
-
A change can be suggested but another team implements it.
-
A pull request can be submitted but it is approved and tested by another team.
-
Fully implementing and testing are possible, but the change goes through a forced/gated code review.
-
It can be implemented, tested, and delivered in production and is reviewed by component mentors without there being a gate.
-
Anyone can review changes at a later time for quality purposes.
-
Belief 5—Technical Quality
The more we work within the same puzzle piece, the more we grow expertise or permanent knowledge of that piece (Ebbinghaus’s forgetting curve—active recall). The more expertise we have, the lower the cognitive load (task-invoked pupillary response results). If we stopped here, we could conclude that putting boundaries on the piece we are working on is an optimal solution. Yet, we will continue elaborating on our reasoning.
Cognitive load is directly linked to working memory, and we know that this is limited or constrained (working memory definition). In other words, there is a maximum cognitive load one can bear day in and day out—a constant.
Time is also constant, and if we have 2 weeks to grow a feature, how far we’ll get is dependent on how effective we are. If we are extremely effective, or have time left, we will use the free time to “gold plate” and make things more complex than they need to be. If we continuously have more time than is required, the extra complexity becomes no longer bothersome; rather, executing on it becomes a habit. Instead of looking for easier, smarter ways to do the same, we tend to always “go for gold”.
The same counts for cognitive load—there is a sweet spot that we, as human beings, tend to find joyful. For some, that’s a very heavy load, while for others, it’s the opposite. Daniel Pink's research emphasizes that humans seek mastery, which drives our engagement and motivation. When we're not intellectually challenged, we become bored. So, finding the right balance of mental effort is crucial for motivation. Let’s be honest, when our intelligence isn’t addressed properly, we just feel bored, don’t we? And who wants boredom? Nobody, of course.
-
Cognitive load is too low = boredom.
-
Cognitive load is too high = stress.
-
Cognitive load sweet spot = motivation.
Considering that cognitive load is the sum of its three types: germane, extraneous and intrinsic, lowering one will incentivise us to increase another as we strive for the sweet spot that results in motivation.
Lowering germane cognitive load by limiting scope of ownership may seem beneficial. However, this can lead to neglecting other areas of cognitive load that also require attention. Ignoring practices that reduce the other aspects of cognitive load results in less readable code, reduced collaboration, and fewer safety nets.
Limiting the scope of our responsibilities reduces the incentive to find ways to lower overall cognitive load. Conversely, broader responsibilities encourage us to seek ways to manage cognitive load more effectively.
While experts may excel in their specialized areas, others not involved in that context may struggle. This creates dysfunction in larger organizations:
-
It becomes very difficult to increase capacity on a piece of the solution when it requires significant change in order to develop new business value. Onboarding new people or those from elsewhere in the organization isn’t easy either.
-
It’s (at least) equally difficult to replace people within the team that owns part of the solution. The resulting knowledge bottlenecks are accompanied by the risk of such individuals leaving the company.
-
As only certain people can touch certain pieces of the solution or product, we end up with dependencies to manage and track. This produces extra layers of cost, and people will need to handle this to the best of their ability.
-
Customers don’t care about pieces; they care about their needs being met, and in that sense, we intentionally create a disconnect between customers and those trying to help them, e.g., misunderstandings, handovers, Chinese whispers, broken telephones. This results in unneeded features.
Then again, experts will add code to this piece of the puzzle faster than any other person would. The question to continue asking in this situation is: Is this piece of the puzzle truly valuable for our business and customers at this moment in time?