Trade-offs in a Microservices Architecture

Kenny Bastani
97 Things
Published in
3 min readFeb 26, 2020

Is there an optimal software architecture? What does it look like? How do we measure ‘optimal’ when it comes to building and operating software? An optimal software architecture is one that has maximal flexibility for change at the lowest possible cost. Here, cost is measured in terms of certain qualities that represent a software architecture’s design and implementation — in addition to the cost of the infrastructure to operate it. The defining trait of a software quality is that it can be tangibly measured and has an impact on other qualities.

For example, if a software architecture requires strong consistency guarantees, there is an impact on qualities like performance and availability. Eric Brewer created CAP theorem to describe a set of measurable trade-offs where you can only choose two out of three guarantees for running a database: consistency, availability, and partition tolerance. The theorem states that when applications share state across the boundaries of a network, you must choose between consistency or availability, but you cannot have both.

One of the main problems with microservices is that there is no single comprehensive definition. Moreover, microservices are a collection of concepts and ideas that are based on a set of constraints for delivering a services architecture. A microservice, or any piece of software you build, is a history of choices—which will affect your ability to make new choices today.

Microservices may not have a single definition, but they do most commonly have the following characteristics.

  • Independent deployability
  • Organized around business capabilities
  • Database per service
  • One application, one team
  • API-first
  • Continuous delivery

As you go out into the world of software development, you will eventually find that there is no such thing as the right choice. Indeed, most developers or operators might believe there is a best choice, and you may find that they argue strongly in favor of that choice. As you encounter more and more opportunities to make a decision between multiple choices, for instance, which database to use, you’ll eventually come to discover that all available options introduce certain trade-offs. That is, you will usually have to lose something to gain something.

Here is a short list of trade-offs you might encounter when making a decision to include a dependency for your microservice:

Availability — How often is my system available to its users?

Performance — What is the overall performance of my system?

Consistency — What guarantees does my system provide about consistency?

Speed — How fast can I deploy a single line of code change to production?

Composability — What percentage of an architecture and code-base can be reused instead of duplicated?

Compute — What is the cost of my system’s compute under peak load?

Scalability — What is the cost of adding capacity if peak load continues to increase?

Marginality — What is the average diminishing marginal return of adding developers my team?

Partition Tolerance — If a partition in the network causes an outage or latency, will my application experience or cause a cascading failure?

How does answering one question affect answering the others?

You will often find that all of these questions will have some kind of relation to the other questions. If you ever find yourself making a tough decision in a software architecture that uses microservices, come back to this list of questions.

--

--

Kenny Bastani
97 Things

Passionate technology evangelist and open source software advocate. International speaker & author of O’Reilly’s Cloud Native Java.