Strategic decisions can be hard. I’ve seen many decisions go bad during my career in software development.
From prematurely implementing a microservices architecture, adopting cutting-edge tech stacks to hyper-specialization on small teams, there are many decisions that can hurt the business. Those decisions aren’t inherently bad, but they can go wrong if they miss the context.
Those decisions can inadvertly create a challenging environment for the business, preventing it to perform optimally.
I saw teams failing to realize that some decisions went bad. Wondering why that is the case, I decided to write what’s on my mind. To understand why deicisions can go bad, first we must understand what makes something good or bad.
Morality is hard
When we say words like poor, good, and bad, we must remember those carry relativity implicitly. By using those words, we are trying convey the meaning that we’re optimizing for something. To illustrate, consider you are trying to lose weight. Consuming carbs can be considered bad, because it will hurt your weight-loss goal. But if instead your goal is to run a marathon, carbs are a great way to fuel your energy reserves before the race.
This silly example is to show that carbs aren’t inherently good or bad. It depends on what you are optimizing for.
Every time we use those words we must remember they are relative to something. There are no absolute good or bad things. This is why morals and ethics are hard. Those words always require some context to have their meaning.
Therefore, in order to define a technical decision as bad or good, we first must set our goals straight: What are we trying to optimize for? When developing software as part of a business’s value stream, we shall look at what the business context. What the business itself is optimizing for?
This line of thought can sound too obvious, but sadly, this is often missed by a lot of tech teams.
Now, what is the business optimizing for?
Economy is everything
Every business is different, but we can say some foundational aspects are common to all of them. For instance, every business must ultimately optimize for profit in order to survive. Unprofitable businesses are going to eventually die when investors stop paying their bills. Businesses earns their profit by providing value to the market while keeping costs under control. The positive delta is what we call profit.
Since markets are made of economic entities with finite resources – we naturally have a competitive environment for any business. At any time, another business can capture market share by providing a more compelling solution. Compelling here is subjective as every economic value is: it can be quality, cost-benefit, or whatever those economic entities value.
If a business must provide value to the market and competition poses risks, it means it is critical for a business survival to remain competitive. It must be able to adapt fast to the market. And if this value is provided by digital products, technology teams must also optimize for a faster ability to change.
This is why continous delivery is so important. This is why it is essential that the high-level design of any technical architecture must follow the business conceptual architecture, hence why DDD is important. If you can change your technical solutions as fast as you can plan and adapt your business model to the market needs, your business will remain competitive, increasing its survival odds.
Technical teams and leaders often forget about this. We focus too often on technical aspects. If you decide to go for a microservices architecture even though it makes perfect sense to have decoupled and independent software components, you’ll inadvertently step into distributed systems realm, which can slow down your develoment teams if they lack the knowledge or then needed tooling.
In such scenario, in addition to materialize the business model, the team must also deal with technical complexities such as data consistency. Now you need to hire more people, which increases the cost of the business, which lowers the profit, which makes the business less competitive. Do you get it? It is a chain reaction. Technical decisions can have a huge impact on the business by adding complexity to deliver value.
Choosing a cutting-edge tech stack can be equally dangerous: it can be hard to hire or train more people on that stack. If you need to change software faster by scaling up your teams, you might get limited by certain technology choices.
Hyper-specializing your tech team is also a common pattern that slow down whole companies. This is a trend in our industry that particularly dislike. For instance, when we break down software development into front and back, we add the need for a more careful resource planning. Backenders can block the work of frontenders if something goes south. Sprint planning then becomes a Tetris-like problem where you want to keep everyone busy while making sure such task dependencies do not cascade throughout the roadmap in case of delays or poor estimation.
Wouldn’t a more generalist team be more efficient? I believe so. If a team can reduce the overall complexity of its tech stack in a way to avoid the need for specialists too early, it can deliver value faster.
How to make good decisions then?
I hope the answer is clear by now. It depends. As mentioned, good and bad depends on what you are optimizing for. There are no absolute correct answers nor silver bullets. If you are developing software for business, look at what the business must optimize for. Always keep the focus on that when making decisions.
To tech leaders: avoid introducing accidental complexity to your teams as much as possible. Pay attention to the details on how the technology impacts your business and what resources are available when facing important decisions such as architecture, tech stack, and team structure.
Forget what other companies are doing, focus on your context. There is no silver bullet.