Delivering on an architecture strategy
December 9, 2019
Software companies always have an unended stream of product features for engineers to work on. One of the most important responsibilities of a technology leader is to carve out space so that engineers can also perform the technical work which keeps the architectural foundations of a product healthy. Just as product leadership are responsible for defining a vision for a product and leading towards it, tech leadership is responsible for defining a vision for architecture, and leading towards that.
In this article I’ll show that we can achieve a sustainable balance between feature delivery and foundational architectural work by empowering teams with autonomy, and fostering a strong partnership between product and tech on within those teams.
We’ll also see that autonomy isn’t enough. To make coherent progress on architectural goals, our teams also need to align behind a shared vision. The Strategic Architectural Initiatives framework delivers that alignment, allowing you to reap full benefit from your high-performing teams.
Finding time for technical work
Thoughtful prioritization of engineering backlogs is important, given that engineering time is a permanently scarce resource. In a product delivery team, the majority of the work performed by engineers is feature work - implementing product functionality. Since product managers are typically responsible for defining features, and teams spend most of their time working on features, it makes sense that the product manager is also the person who prioritizes what the team works on1.
However, there’s another type of work - architectural work - that’s just as important to the success of a product. It doesn’t directly deliver product value, but rather delivers the foundation upon which that product value is created. I’m talking about “platform work” such as creating shared services that allow engineers to more efficiently build product features, as well as architectural improvements such as the monolith breakups and cloud migrations that every engineering org seems to be working through.
It can be challenging to get architectural work prioritized appropriately, particularly when the person prioritizing the team’s backlog doesn’t know about this technical work, or doesn’t fully understand the value of the work. Sometimes the need for this technical work is simply not communicated well. A CTO or Chief Architect might have a clear vision of what’s needed, but if the product manager - who defines and prioritizes a team’s work - doesn’t understand that vision then progress will inevitably be disappointing. In other circumstances, a product manager might understand some of the technical tasks, but not see how they contribute to a strategic outcome for the team or the product. In both these situations, it’s hardly surprising that we’d see an inbalanced prioritization of feature work over architectural work.
There are various project management techniques that attempt to correct this inbalanced prioritization artificially. A team might reserve a percentage of their capacity for “tech debt work”. Big architectural initiatives might get bundled up as a technical project, with that project assigned to a team, or with a new team formed expressly to work on it. There are times when these approaches make sense, but leadership should consider them a solution of last resort. Managing technical work and feature work as a single backlog is much more effective. Pulling from a single backlog gives a team more flexibility in prioritizing and load-balancing across different tasks, and is a natural fit for teams that are product-oriented, as opposed to project-oriented.
So, a team that’s pulling a balanced mix of technical and feature work from a single backlog is the ideal. The best way to reach this ideal is with autonomous teams who are aligned around a common technical vision.
Enabling a balanced backlog
I’ve been lucky enough to work with several high-performing teams over the years, and I’ve noticed that these teams have had two things in common. Every team has had a strong sense of product ownership, and a high degree of autonomy.
Product-oriented teams foster product/tech partnership
High-performing teams have technical folks who care about the business domain they work in and the product they are building, a product manager who understands that product value stems from a strong technical foundation, and a mutual trust between team members that they have a common goal. I’ve seen this type of product/tech partnership most naturally occur with product-oriented teams - teams that have long-term ownership of a “vertical slice” of product functionality. This makes sense - everyone naturally develops a sense of responsibility for the ongoing success of the systems which they own, as well as an understanding of the business which those systems support. In addition, the long-lived nature of the team gives product and technical folks time to develop mutual trust.
When a product manager trusts that the engineers on the team have the interest of the product at heart, they also trust the engineer’s judgment when adding technical tasks to the backlog and prioritizing them. This enables the balanced mix of feature and technical work that we’re aiming for. However, this is only true if the team are empowered to manage their own backlog; if the team has autonomy…
Autonomous teams make better decisions
I’m a big fan of autonomous teams. The people working on the ground - the individual contributors - naturally have the most in-depth understanding of their work, and an intimate awareness of the current situation. Empowering these people to make tactical decisions just makes sense. This is known as Mission Command - something I’ve written about before.
However, empowering teams to make decisions locally is only helpful if they also understand the broader context.
Aligned autonomy
Imagine you’re hosting a dinner party, and your friend Sally asks what they can contribute. Some of the guests are vegetarian, so you ask Sally to make her well-loved lentil curry. You explain to Sally why you’re interested in the lentil curry - some guests are veggies - but tell her she’s welcome to bring something else if she’d prefer.
As Sally starts to prepare the dish, she realizes she’s all out of lentils. Luckily, Sally both understands the vision (contribute a vegetarian dish), and has autonomy on how to deliver that vision. We call this Aligned Autonomy.
Sally decides to change the plan, and makes her famous green bean casserole instead. This is a good outcome - Sally’s understanding of the situation on the ground improved, she adjusted the plan accordingly, and we were able to achieve our objective - a wonderful dinner party.
Autonomy without alignment isn’t useful
To understand why autonomy isn’t that valuable without the alignment part, let’s consider an alternate reality. Imagine that you’d told Sally she was free to bring something other than lentil curry (again, autonomy) but you neglected to also share the broader goal with her (that we need a vegetarian dish).
Sally realizes she’s out of lentils, and again uses her autonomy to change the plan on the fly. But this time she doesn’t know what the broader goal is, so she makes a (wrong) guess: “It’s probably an Indian-themed meal”. She then exercises her autonomy, but in a way that isn’t helpful: “I’ll cook chicken tandoori instead”.
This is clearly not a great outcome in terms of achieving the broader objective. We’ve squandered the benefits of autonomy, thanks to a lack of alignment.
I’ve seen examples of this sort of unaligned autonomy play out all the time within engineering organizations. Individual delivery teams are working on technical initiatives that seem strategic to them, but a lack of alignment across those teams means that there’s little forward progress on an architectural level. Perhaps a platform team is investing heavily in a Kafka-based event-sourcing architecture, while a product team is cooking up their own solution based on RabbitMQ. Or, a product team is investing all their spare engineering cycles in reducing the latency of their API, while improved analytics capabilities would be much more valuable for their operational stakeholders. Despite each team feeling that they’re making good technical decisions locally, but there’s no coherent progress at an organizational level.
Connecting technical work to business outcomes
A technical strategy does not exist in isolation. It should be in service of broader product- or business-level objectives. For example, a technical strategy to accelerate deployments might be driven by a product objective of responding more rapidly to feature requests from customers. Put another way, our technical strategy should be aligned with our business objectives, and we should be concerned if we can’t easily connect technical work back to a broader business goal.
A technical strategy gives us a broad technical objective; too broad to be actionable. Handing a vague goal like “accelerate deployments” down to engineers won’t result in coherent progress. What’s needed is a more detailed plan that bridges the divide between high-level objectives and the work of individual engineering teams. A technical strategy provides the “what”, but we also need the “how”. That’s where an architectural initiative comes in, laying out the specifics of an architectural change which will move a technical strategy forward.
For example, given our technical strategy of accelerating deployments, we might define an architectural initiative around creating a fully automated delivery pipeline, and perhaps a second initiative around establishing a shared test automation platform.
These architectural initiatives connect the dots from broad business objectives down to something that individual engineers can get their heads around and execute on.
Here’s another example. Our CEO wants to broaden the business’s total addressable market by launching two new products within the next 18 months. That’s our business-level goal. Our VP of Engineering decides to support this business goal by extracting a small platform of shared services from the existing product. That’s our technical strategy, based on the expectation that this shared platform would allow our engineers to build these new products more quickly. To start executing this technical strategy, we decide to extract user accounts management into a separate service, and to extract a common UI framework - two architectural initiatives.
Strategic Architectural Initiatives
An architectural initiative needs to clearly articulate a specific technical plan, connect it back to broader strategy, but still allow teams to leverage their autonomy in a way that contributes to that plan. A Strategic Architectural Initiative (or SAI) is a format for achieving this.
The three elements of a shared vision
A Strategic Architectural Initiative breaks down into three parts:
- Where do we want to get to (Target State)
- Where are we now (Current State)
- What are we doing next (Next Steps)
These three parts describe the current situation, the strategic goal, and give guidance on some immediate tactical work that gets us started towards that goal.
An example SAI
We can explore this framework in more detail using an example. Let’s say as a CTO I want to ensure that we have a well-understood strategy regarding our product’s tech stack. Everyone must be aligned behind my vision here, so I use the Strategic Architectural Initiative framework to get everyone on the same page. Here’s a thumbnail sketch of how I’d communicate this SAI:
Current State: We’re mostly a Java shop, but a few teams have been experimenting with Scala, and one team recently snuck a Golang service into production.
Target State: Within a year, we will have built a platform which provides first-class support for Java and Scala, and won’t be running any other technology in production.
Next Steps: This month, we’re kicking off work to build the first iteration of a framework for running Scala on our platform, harvesting some of the ideas from our Scala experiments. We’re also be officially deprecating that Golang service, and starting work on a replacement.
Each piece is important
Unless we define all three of these elements clearly, there is a tendency for people to fill in the blanks themselves, often in incoherent ways.
Without a clearly articulated Target State, there’s a risk of people extrapolating their current work out into an incorrect long-term goal. For example, imagine if the CTO just said “as part of rationalizing our technology stack, this month we’ll be starting to build out a Scala framework”, without also explaining the longer-term Target State. Some teams might incorrectly infer that we intend to deprecate Java, and start research on moving their Java services over to Scala.
It’s hard to focus energy without well-defined Next Steps. Some delivery folks might start working on new Scala services before a basic framework has been created, or perhaps two different teams would both start working on their own Scala frameworks. Note, though, that while the Next Steps element is a critical piece, we must avoid being overly prescriptive. We should not be describing how we’ll get all the way to our Target State in great detail. We’re practicing Mission Control here - our goal with the SAI is to communicate strategic direction, with the Next Steps piece providing an additional perspective to help teams understand that broader strategy.
Without a shared understanding of Current State, some engineers might not think the Next Steps make sense. The engineer who’s been working on the rogue Golang service might have had no idea that it’s the only Golang service in production, and not understand why we are planning to deprecate it. An objective description of Current State can also help non-engineering stakeholders to understand why this architectural initiative is necessary.
Doers and Dreamers
Different people think differently. Some people are “doers” who focus on the task directly at hand. Other people are “dreamers” that tend to think strategically, paying more attention to the long-term end goal. I’ve found that it’s rare to find people who think deeply about both the current reality and future goals.
Deconstructing an initiative into Current State, Target State, and Next Steps ensures that you’re filling in the gaps for all the types of thinkers that need to get behind the initiative. Target State helps Doers to see beyond the tactical stuff that they tend to focus on, towards the broader strategy. Curent State reminds Dreamers of the reality today, rather than what they think it should be in the future. Next Steps allow everyone to connect the dots between where we are today and where we want to get to, and ensure that the initial activities kicked off in pursuit of our strategy are coordinated and coherent.
Building an SAI
So how do we go about actually creating these Strategic Architectural Initiatives? And what do we do to make sure they’re broadly understood? Luckily for you, I’ve written a separate post covering just those topics!
Sustainable progress on tech is hard, but achievable
Many engineering organizations struggle to make meaningful progress on big technical goals after they scale beyond a handful of engineers.
It’s hard to carve out the bandwidth for technical work, and even if you get that bandwidth, it can be a real challenge to “herd the cats” and get different teams to work towards the same architectural goals without micro-managing every team.
In this article, I’ve laid out some approaches and tools which address these challenges. Autonomous teams reduce the need to micro-manage, and product-tech partnership helps to ensure that teams can allocate time for technical work which drives business outcomes forward. Strategic Architectural Initiatives help to focus firepower and ensure that the technical work that teams are doing is coherent, and delivers on broader organizational objectives.
I’d love to hear from people who are applying ideas like this, or who have an alternative approach. Please get in touch and tell me all about it!
Acknowledgements
My sincere thanks to Pat Kua, Brad Henrickson, and Jeff Parvin for their thoughtful feedback on an early draft of this article.
- in some enterprise organizations work might be defined and prioritized by a product owner or a business analyst, rather than a product manager. The distinction isn’t important here. [return]