Michael Nygard is a well-known software engineer and architect. He designed and delivered some large-scale systems in his career and distilled some of his insights in his book Release It! . He is also a renowned expert in the area of microservices. This month, he is visiting Germany to give his workshop “Monolith to Microservices” in Solingen and Munich. We had the opportunity to interview him.
Uwe Friedrichsen: Microservices are no longer a hype. They have become reality in many companies. Even more companies have just started picking them up. And some companies with special requirements like Segment already stopped using them . What is your opinion regarding microservices? Are they the long-searched-for panacea as some say? Or are they Pandora’s Box as others say? How do you experience microservices?
Michael Nygard: As the saying goes, there’s no silver bullet. Microservices are a technological solution to an organizational problem. That problem is, “How do I scale my development team without paralyzing development flow?”
I also think microservices are the result of failures in our operating systems, languages, and frameworks. Basically, the goal is fault isolation and independent deployment. We want each team to deploy on their own schedule without causing downtime to other teams. We also want to prevent bad code in one service from harming others. This is only partly achieved with microservices today. Third, we want to isolate the OS level namespaces—IP addresses, TCP ports, file names, directory contents, etc.—from each other. Finally, we want to enforce architectural boundaries between the services. Do these really require us to run thousands of containers, each with their own operating system image?
Uwe: You already touched upon it in your previous answer, but just to get to the heart of it: when do you think, using microservices is a good idea?
Michael: They’re a good idea when you need independent deployment across multiple teams.
The reality is that adopting this architectural style means constant redesign and evolution.
Uwe: While I feel I already know your answer, let me ask you nonetheless: when should you better refrain from using microservices?
Michael: If you are a small team working cohesively, like in a single room, then you are better off avoiding the operational complexity of microservices.
Uwe: If you look at your customers, what are – based on your experience – their biggest challenges when picking up microservices? What do they really struggle with?
Michael: There are two big hurdles. First, many people pick up microservices but don’t do enough design of the APIs between the services. As a result, they build a distributed ball of mud, where every service can call every other service. That results in rigidity at a higher level, since nobody is free to change their APIs.
Second, a lot of groups that pick up microservices think they’re just going to design things once, build a set of microservices, and then be done with it. The reality is that adopting this architectural style means constant redesign and evolution. You may delete a service that you just created last month, and you have to be willing to accept that. It can be uncomfortable, because we’re used to thinking of code as a long-lived asset.
Uwe: Facing those challenges: what are your recommendations? What are the most important topics people and companies should be aware of if they decide to adopt microservices?
Michael: First, they need to be aware of the nature of distributed systems development. Developers should be comfortable drawing Lamport diagrams and talking about idempotent messages versus “exactly once” delivery infrastructure. That’s already a prominent part of system design and it will only become more important. I extend this all the way to the front-end as well, by the way. Modern front-ends are applications in a distributed system with all the uncertainty and asynchrony that implies.
Second, I think developers have gotten plenty of discussion about the virtues and perils of microservices, but most have little experience designing the services and evolving their APIs. What I mean by that is, you can find hundreds of tutorials about setting up Kubernetes or how to use Docker to deliver your code to production. But there isn’t as much about how to design a good service, let alone how to build a whole system out of such services. Developers must avoid falling into the trap of making their microservices act like distributed objects or entity services. That was a big part of the motivation behind my “Monolith to Microservices” workshop. In that class, developers build real services and we talk extensively about making usable, evolvable APIs.
You can find hundreds of tutorials about setting up Kubernetes or how to use Docker to deliver your code to production. But there isn’t as much about how to design a good service.
Uwe: Okay, that is quite a bit to ponder regarding the adoption of microservices. Let us finish with a look into the crystal ball: Do you think microservices will still be relevant in five years? Or will they be replaced by a new paradigm? Or will we be so absorbed with totally different challenges that we simply won’t care?
Michael: I’m going to predict what I think should happen, in the hopes that I can simply wish it into being true. Our languages and platforms today don’t help developers express the design of a distributed system. We’ve got languages for writing code that runs inside a process on one machine. Then we try to assemble that code together with functions-as-a-service, a pile of infrastructure-as-a-service using some other languages and tools. Then we somehow expect that the assembly respects the wire protocols, preconditions, and invariants that we planned for our system. Yet there’s no way to assist the humans in making the whole assembly correct.
By that I mean that we have things like unit tests, type checkers, linters, and so on that help us get the code right that runs inside a single process. But when it comes to coordinating processes across a network, we don’t have tools to assist the developer or designer. So what I’d like to see in five years is something like this: We have a true distributed operating system, in the same sense as a server operating system. It provides an abstraction over hardware, resource management, an API, visibility, operational tools, etc. We have a language that lets us describe the connections between processes in terms of their data formats and invariants, and we use the same language—or something very similar—to describe the code inside the processes. When we hand a system written in that way to the operating system, it will be the job of the OS to make everything run with the right network rules, security protections, isolation, and so on.
I think we can see the beginnings of such a world right now. But each installation is a unique combination of off-the-shelf parts. So you might have Kubernetes, Helm, and Istio, running on AWS with Lambda, etc. I might be using Terraform, Consul, Vault, with applications in Clojure with Clojure.spec. It would be like if every server ran its own hand-crafted version of Unix.
Uwe: Thanks a lot for the interview, Michael!
A German translation of the interview was previously published on heise Developer.
Michael Nygard has been a professional programmer and architect for more than 15 years. He has delivered running systems to the U.S. government and to the banking, finance, agriculture, and retail industries. Michael is a popular speaker at technical conferences, and has written and co-authored several books, including Release It!  and 97 Things Every Software Architect Should Know .
 Michael Nygard, Release It!, 2nd edition, Pragmatic Programmers, 2018
 Segment Blog, Alexandra Noonan, Goodbye Microservices: From 100s of problem children to 1 superstar, see https://segment.com/blog/goodbye-microservices/
 Richard Monson-Haefel (Ed.), 97 Things Every Software Architect Should Know, O’Reilly, 2009