Microservices ate my application - an adoption anti-pattern
anti-patterns architecting deliberative design decision makingIt’s been a while since I’ve written about anti-patterns of microservices adoption. These days, however, I often encounter a previously undocumented anti-pattern that I’ve named Microservices ate my application. It describes a situation where technology - in this case the microservice architecture - becomes a scapegoat for the mistakes made by the engineering organization. The anti-pattern’s name is inspired by the English expression The dog ate my homework, which refers to an implausible excuse for failing to complete a homework assignment.
The anti-pattern: microservices ate my architecture
An instance of this anti-pattern looks something like this. An organization struggles to use the microservice architecture pattern to build an application. They encounter numerous persistent problems, including slow development, inconsistent data, poor performance, and low availability. But instead of taking ownership of the decisions that they made, which is the reason for the trainwreck, the organization blames the microservice architecture.
Swarms of microservices don’t attack projects
While it’s easy and convenient to blame the microservice architecture, the reality is that microservices do not travel in swarms attacking innocent projects. The root cause of the train wreck lies elsewhere - specifically in a combination of two problems. The first problem is that organizations sometimes make poor architectural design decisions. The second problem is that organizations often ignore the warning signs that something is amiss. Let’s look at each problem in turn, starting with poor architectural decision making.
Problem #1: Poor architectural design decisions => poor architecture
An application’s architecture is the composition of a set of design decisions. The quality of an architecture is, therefore, a reflection of the quality of the architectural design decisions. Poor design decisions often lead to architectural problems—an issue that is especially true when using the microservice architecture pattern. There are numerous design decisions to make, many of which are highly consequential. Even small missteps can have far-reaching impacts.
Problem #2: Ignoring signs that something is amiss
The second reason train wreck projects occur is that organizations ignore clear warning signs signaling the need for a course correction. Development projects don’t fail overnight — there are always early indicators that something is going wrong. An organization must be vigilant and act when there are signs that something is amiss. For example, if development is slowing down, it’s essential to investigate why.
Let’s now look at ways to avoid this anti-pattern.
Avoiding the Microservices ate my application anti-pattern
There are four recommended ways to avoid the Microservices ate my application anti-pattern:
- Own your design decisions
- Improve your design decision making process
- Reduce the risk by making smaller, safer and reversible changes.
- Track and improve metrics
Let’s look at each recommendation in turn.
Recommendation #1: own your design decisions
The first of three recommendations is for you and your organization to take ownership of your design decisions.
If a decision turns out to be flawed, take responsibility for it — that’s part of the process.
Mistakes are inevitable, but they also present valuable learning opportunities.
Freedom to admit your mistakes, of course, requires a generative culture that encourages learning and growth.
Recommendation #2: improve your design decision making process
The second recommendation is for you and your organization to improve your process for making architectural design decisions. A good way to make better design decisions it is to practice deliberative design. Deliberative design is a 7-step process:
- Understand the context
- Define the problem
- Define the criteria for assessing the suitability of a solution
- Find candidate solutions
- Evaluate the trade-offs of each candidate solution
- Pick the best solution
- Document the solution
Examples of critical architectural design decisions that should be made using a deliberative design process include:
- Whether to use a monolith first (usually) or microservice first (sometimes) approach when starting development
- When to refactor a monolith to microservices, e.g. Big decisions: Should you migrate your monolith to microservices?part 1 and part 2
- When to define a new service, e.g. A service should exist to solve a problem
Recommendation #3: make smaller, safer and reversible changes
The third recommendation is to reduce risk by making smaller, safer and reversible changes. You will get feedback from production and users much faster if you make smaller changes. It will also make it much easier to recover from mistakes. For example, an organization should incrementally refactor a monolith to microservices using the Strangler Fig pattern rather than doing a big bang rewrite. For more details, see the series of articles that starts with Microservices rules #10: Make smaller, safer, and reversible changes - part 1/
Recommendation #4: track and improve metrics
The fourth recommendation is for an organization to continuously track and review key metrics (microservices rules #1) including:
- The DORA metrics
- Design-time coupling metrics, e.g., analyze Git histories to identify services that regularly change in lockstep and track the frequency of breaking changes made to each service’s API
- Team sentiment including the DevEx metrics
These metrics should be regularly reviewed and action taken if there are problems.
Need help with accelerating software delivery?
I’m available to help your organization improve agility and competitiveness through better software architecture: training workshops, architecture reviews, etc.