Picture Me Coding
Picture Me Coding is a music podcast about software. Each week your hosts Erik Aker and Mike Mull take on topics in the software world and they are sometimes joined by guests from other fields who arrive with their own burning questions about technology.
Produced by Neiko Will.
Logo and artwork by Jon Whitmire - https://www.whitmirejon.com/
Reach out to us here: podcast@picturemecoding.com
Picture Me Coding
Monoliths vs Microservices
Did you ever wake up one day and realize your microservices architecture had transformed into a large distributed monolith? Did your boss come to your house and did your family try to disown you? Mike and Erik have lived that story too!
In this episode they wade boldly into the microservices vs monoliths discussion and Mike makes the bold claim that doing microservices isn't even an architecture!
Articles We Talked About
- Martin Fowler's definition
- "How Engineers Can Accidentally Create Distributed Monoliths"
- https://segment.com/blog/goodbye-microservices/
- Monolithic vs. Microservice Architecture: A Performance and Scalability Evaluation | IEEE Journals & Magazine
- Even Amazon can't make sense of serverless or microservices
[MUSIC] >> Hello.
Welcome to Picture Me Coding with Erik Aker and Mike Mull.
Mike, welcome to your show.
>> Howdy.
>> Mike, what are you even listening to this week?
Tell me about it.
>> I've been listening to this album called Night Rain.
Rain isn't like the "reign of a queen".
>> Like rain in blood?
>> Right.
Okay.
Yeah.
That too.
By this artist named Harouj Afthab.
It's hard to describe.
She does music that is sometimes maybe jazz, sometimes maybe folk music.
She's done a couple of collaborations with the pianist Vijay Iyer as well.
But yeah, I like this album.
It's again hard to describe.
There's some songs that are sort of ethereal and pretty.
There's one song called Bolo Na, which has got this funky baseline, which is cool.
But yeah, I enjoy it, but I don't really know how to convey what it's like to other people.
>> Well, we'll have to give it a try.
I am almost a little embarrassed to admit this because it just seems so deeply lame for a guy in his 40s to be like, "I've been listening to the new Billie Eilish album."
But I've been listening to the new Billie Eilish album.
The music that she and her brother put together is always so sonically interesting.
These songs always evolve and turn out to be different, weirder things than you thought they were.
I like that actually.
Beyond just pop music, they're doing some interesting stuff.
I don't really like it as much as the other one that I discovered after it came out, which was when we fall asleep, where do we go?
It's very slow and kind of jazzy and somber.
What do you think about Billie Eilish?
>> So I did listen to this album once.
I did not love it, but I did not dislike it either.
I do like some of her stuff.
>> Did you listen to when we fall asleep, where do we go?
>> I have listened to that.
There's some stuff that she did in her early part of her career that I liked.
I'd almost put it in a class of stuff like Chelsea Wolf, a little bit sort of gothy maybe, which I liked.
But yeah, clearly she's probably not going for the 60-year-old white dude Democrat.
>> There's just this tinge of weirdness and surprise in the music that I find compelling.
All right, this week, we are going to talk about something our audience has demanded.
This is the great debate of 2024, monoliths versus microservices.
>> This is get your hot takes ready kind of discussion.
Because there are pitched battles happening about this one.
Am I right?
>> There are.
Also, I have a meta question, which is if there are monoliths, are there polyoliths?
>> Can we come back to that one?
I'm not sure I understand it yet.
Let's talk a little bit about the timeline.
So microservices, very popular term, very popular way to build systems in our industry now.
The term really doesn't appear much before 2012 maybe.
So the precursor to microservices, I think we could both agree was probably service-oriented architecture, which is more like a 2000 style.
Netflix, everybody talks about is the company that was the prime advocate for developing microservices.
They did this very early.
Like 2009, 2010, they started separating out a lot of things into microservices.
They started writing about it in 2012.
There were different messaging systems and architectures that made this possible, such as like RPC systems, SO, JSON, et cetera, REST.
Docker comes out in 2013, that's going to be part of the story.
Then Martin Fowler, he undertakes this pretty canonical definition of the term in 2014, and people refer to this definition all the time.
Then you have stuff muddying it a little bit.
AWS is Lambda comes out in 2015.
Sometimes people talk about microservices and they conflate it with something like a serverless functions as a service.
There's a book that I read that I really like by Sam Newman called Building Microservices that comes out in 2015, Kubernetes 2015.
Then you have tooling that arises in order to deal with these systems as well, observability tooling.
So you've got tracing systems like Zipkin from Twitter in 2012, you've got Jaeger from Uber in 2015, a lot of opinions about logging, log aggregation and metric collection, things like that, which make it possible to build these systems.
So it seems like maybe 2012 to 2015, this amorphous concept gels and suddenly everywhere, people in our industry are talking about microservices.
Here it is about 10 years later, and we're still wrestling with this notion.
>> Yeah, still not entirely sure what they are.
>> Well, let's do a definition.
So I'm going to give you definition.
Definition mostly cribbed from Fowler.
His well-known post on this is called Microservices, a definition of this new architectural term since 2014.
This is also pulled from Sam Newman's Building Microservices in 2015.
So I pulled four attributes out.
These are smaller services, already maybe a fuzzier designation, smaller services.
They have singular responsibilities.
Fowler talks about it more like the Unix style of binaries that you pipe together.
They have one job.
They're organized by business units.
Fowler says product, not projects.
Smaller services, single responsibilities, organized by business units, and finally deployed independently.
So not this massive application, but little things that you deploy independently.
What do you think about this definition so far?
>> I've always had a number of issues with the definition of microservices.
I think the last point is probably the one that's the most solid for me, the deployed independently part.
I think that's a generally good thing and it's not too ambiguous.
But all the other points, I think are imprecise and I think that's probably my biggest issue with microservices in general is when does the service become small enough to become a microservice?
>> What is a singular responsibility?
How fine-degrees does that have to be before it's singular and not a collection of things that are somehow related?
I really don't know if I even agree with the products, not projects thing, but I also don't really understand what he's getting at there.
>> To me, that one is the least tangible for most of the software engineering teams I've been on.
We can say, "Oh, this is smaller than this 100,000 line software application.
It's a lot smaller, maybe it's 10,000 lines."
It has a responsibility that seems a little more confined than the 100,000 line application.
But I think you're reaching for something that comes up a lot in this discussion, which is are we just using our gut, our instinct to determine what the boundaries are?
What goes into this thing and what gets cut out of it and how small is micro and maybe I don't want micro, maybe I want medium size.
>> Or maybe you want Nano services.
>> Nano service, that sounds horrible actually.
What do you think?
Is this an architecture?
How would you describe this?
>> Microservices is not really an architecture, it's an abdication of architecture.
>> What does that mean?
It's not an architecture, it is an abdication of architecture.
What does that mean?
>> My issue with these and just to be clear, I'm not anti-microservice, I think there are a lot of good things in the idea.
But I think when a lot of people come to these, the appeal to them is, "Okay, it's smaller, a smaller team can work on it.
It has a more well-defined purposes and better-defined bounds.
It's going to be less complex.
It deploys independently.
My team can work on this thing and deploy it independently of the overall application."
All those things are good, but they never talk about how that thing is put together with other microservices to make applications.
>> When we talk about a single thing, it's I can hold that single thing in my head if it's quote unquote small enough.
If I deploy it independently of other things, and when I deploy it, I'm not going to break those other things.
That sounds great.
>> Your comment is, it's not an architecture to just talk microservices because you would then have to always imagine, how does my thing relate to every other thing?
>> Yeah, I mean, there's two scenarios.
One is that you're just really building a small application, and it doesn't really need to talk to anything in the outside world.
Maybe it publishes an API, obviously, and maybe it calls some third-party thing, but it really never needs to talk to other services and so there really is no architecture there other than a service for which you can write a client.
The other possibility is that you do combine your microservice with other microservices to build some application, but there's nothing in what you've done that specifies how that happens.
There's a lot of debate about what the best way to do that is.
>> Right.
Okay.
So that's the ambiguity part.
What you're saying reminds me of this line from Don Delillo's white noise.
It's like you're accusing microservices of not being an architecture.
It's like an architectural style.
Then white noise Delillo is talking about this.
We want to see catastrophes, but they have to happen somewhere else.
This is where California comes in.
They have mudslides and brush fires and mass killings.
Actually, this is for white noise.
He says, "We can relax and enjoy these disasters because in our hearts, we feel that California deserves whatever it gets."
Californians invented the concept of lifestyle.
This alone warrants their doom.
But I digress.
So you're calling microservices an architectural style.
>> A microservice lifestyle.
>> Well, wait a minute.
Can we do the comparison to Monoliths?
Monoliths, I guess, I would think, and you could school me on this.
I just think, the beginning of my career, I did a lot of pithon-jango framework, and we would pack everything in there.
I did have an application I worked on that was 100,000 lines of pithon-jango.
But there's also the Rails, Ruby on Rails, or very large Java applications.
They do lots of different things.
Fowler makes the comparison to Monoliths in the following way.
For the Monolith, he writes, "Change cycles are tied together.
The change made to a small part of the application requires the entire Monolith to be rebuilt and deployed.
Over time, it's often hard to keep a good modular structure, making it harder to keep changes that ought to only affect one module within that module.
Scaling requires scaling of the entire application rather than the parts of it that require greater resources."
>> That's Fowler in 2014.
Do you have any disagreement or you have anything to complain about in that comparison of Monoliths?
Does he have Monoliths right, you think?
>> He does.
I agree with the last point pretty strenuously.
I think the idea that you can scale things independently is a very important aspect of microservices that a lot of people overlook.
>> That links to your point about deploying independently as a concrete thing.
>> Yeah.
Being able to deploy independently, I think is an ambiguous win.
>> That leads directly to scaling independently.
Sorry, go ahead.
>> The fact that you can scale independently is a pretty clear win.
That's one of the key benefits of Cloud Stuff in general.
You can scale, compute, and storage independently because they're not all in the same computer anymore.
But the other parts I'm a little less on board with, I think it's not that he's wrong in the idea that as the monolith gets bigger, it's harder to modularize and you get complexity and probably coupling that you don't want.
I just think that microservices don't solve that as well as people claim they do.
>> Interesting.
He might be right in the way he's characterizing the monolith, comparing microservices to monoliths.
But you're saying that the medicine is not a cure for the disease.
>> Okay.
Yeah, I like that metaphor.
>> We're going to go with Fowler's characterization of monoliths here for a bit.
I want to say why would people want microservices?
In an ideal world, let's say we agree on the size of things, we can cleanly break them up.
The reasons that you see why people would want these things, and this is Fowler, this is Newman, it comes from other people talking about this as well.
One of the first things that comes up that always surprises me is, you might want microservices because you want different groups of people to work on things.
It's a human thing.
You want this group of humans to work on something separated from this other group of humans.
That's interesting to me because that's not a technical constraint, is it?
>> I don't think so.
We've talked a lot about in past episodes and other contexts, we've talked about the famous two-pizza team.
>> AWS, yeah, or Amazon.
>> Engineers, I think, do think that smaller teams focused on a particular purpose work better.
If you have five people working on a well-defined thing that they can deploy independently, that's a better organizational structure than having 20 people working on a monolithic application and trying to stay out of each other's way.
>> In some sense, as I goes back to Fred Brooks, right, Mythical Man Month.
>> Yeah, I think there are variations on this, but yeah, the idea that adding more people to a project is not necessarily give you linear scaling in terms of your productivity.
>> Yeah, even if you have, I've worked on what would be considered monolithic applications in the distant past where we had bigger teams, and it was the same code base and it was probably deployed as one thing, but we did have subgroups within that team that we're working on particular parts.
So there's an organizational aspect to trying to coordinate the release of that thing even though there are subgroups within that product team that are not really working on the same stuff or interfering too much with each other's work.
>> The interesting thing about what you're saying is when you separate, when you have smaller teams, it actually can be a contributor to less technical complexity.
This is where they talk about how the communication structures of an organization lead to the way in which software is typically built.
We tend to ignore how human a lot of these processes are, software engineering processes.
Anyway, you might want microservices because you want different groups of people to work on different things.
Fowler calls this quote, decentralized governance.
Who owns what?
You might also want to use them because you want to break up responsibilities into separate services because you want to achieve some overall complexity reduction or what we've said a number of times, you want to scale these pieces independently.
Maybe you've got some application which has some web component, maybe it's got some published JSON API and JSON API is going to be used by servers.
You want to break these up, scale them independently.
The servers are maybe going to do a lot more interactivity than the humans are potentially and maybe it seems more complex to break them up.
You might also try to break things up into microservices because you want to achieve some loose coupling between these things.
The goal there is more about fault tolerance.
If this part of the application goes down, I don't want it to take down all these other parts of the application.
If I carve it out and kick it out over here, it might protect the other aspects of the organization.
Now, there's a term that I first encountered in Sam Newman's book.
This is where I think we get into a lot of arguments.
The term is bounded contexts.
This goes back to Fowler's products, not projects thing.
A bounded context is a little bit of an amorphous idea than a product, I guess.
Although product might be amorphous too, but it's like, can I draw a boundary around functionality and call that a bounded context?
If they exist and they're obvious, then you might want microservices to deal with those.
A couple more, you might want to use different languages and different technology stacks.
Maybe you want something for the data scientists and data engineers to use that's different from people doing high-performance computing to use.
You might have a really straightforward and easy way to deploy your stuff, so you don't have the problems with independent deployability.
There's a lot of reasons why you might want microservices.
You're complaint so far as well, when we talk about microservices, it's very fuzzy.
It's pretty amorphous.
You're talking about "smaller services."
What the hell does that mean?
What do you think about these as the reasons why somebody might reach for these things?
I think they're all more or less valid.
I think there's some of them that I don't think are really all that exclusive to microservices.
The easy deployment is, I think, something that goes with microservices and the ability of groups of people to work on different things.
Maybe even there, I think you don't necessarily have to do microservices to accomplish a lot of these things.
Again, I've worked on projects in the past where we were building a desktop application.
At the end of the day, everything was compiled into one binary, but there were still groups within that organization that were doing different things from in a conceptual level.
Some people were working on things that were more business logic, and some people were working on things that were more in the UI context, and some people were expert on the data layer and things like that.
I don't think you necessarily have to have completely separate deployable entities to break things, to have organizational decoupling.
Bounded context, I think, is another thing.
I don't think you necessarily have to do things as microservices to have bound context.
It sounds like you're saying it is possible to organize things.
If we're just trying to use this to organize what we're doing, then our efforts are probably doomed to failure because this is not an organizational technique.
It's not going to teach you organization, maybe.
That's what's not going to happen.
Well, I think it forces a certain type of organization on you.
What I see when people come to microservices or when I see people advocating for microservices, it tends to be the organizational things that they are fighting for rather than what I see as the essential features of microservices.
I almost never hear people say, "I want to do microservices because I can scale them independently."
I hear people say, "It's a more focused thing, and my group can work on that, and it's less complex."
I see it deploys separately, and that makes my life easier because I have to worry about orchestrating some sort of big release and all that kind of stuff.
I rarely hear people talk about the things that I think you really win with microservices.
Here's my question for you.
Are people making this decision in our field, not massive companies, but people in small and medium-sized companies?
I've worked in one massive company and one medium-sized company and a couple small companies, and microservices were common.
Is your sense that people are reaching for these because they're making a gut-level decision for them, but they're not looking to this literature in our field and saying, "Yes, these are the reasons why people should do this.
We have these reasons.
Let's do that."
Is that what you're saying?
Yes, I think there are, especially in smaller companies, people have heard that microservices are a useful thing or they are good technology and that Amazon is using them and Netflix is using them, so they must be valuable because those companies are succeeding with them.
They make this decision to do microservices, but what it turns into is they're just taking an application that would have been something returning HTML to their front end, to something which is a JSON REST API.
Maybe it looks like a microservice, but it's not really talking to other microservices, so it's just basically a small application.
A small monolith is what you're saying.
It's a small monolith.
Is there something truly new about microservices in your mind?
Is this a completely new way to build applications?
I think it shares a lot of characteristics with stuff that was happening in, at least by the late '90s, early 2000s.
People have forgotten this now because it's been so totally overtaken by web applications, but there was a huge craze in the late '90s and early 2000s for what people were calling component-based software.
Should I have heard of that?
I've never heard this term, component-based software.
Probably in the late '90s or early 2000s, if you were doing, say, Windows development, you were probably working with COM.
DLLs is what you're talking about?
Yeah, you're making dynamic link libraries.
It's sort of an interface that you would program to, and COM was this attempt to make sort of like a binary level interface.
You didn't have to use a specific language.
You could bind to this service at sort of a binary level.
That's interesting.
So it's like coding to the contract kind of, like between services.
And there was this idea that you could create these so-called components, and you could assemble those together into applications.
And so it was kind of an idea that was spun out of object-oriented programming, but the idea now is that instead of being a class in the program that you're writing, it's now this separate entity that is probably deployed as a DLL or some other type of deployable thing.
What I'm hearing is that our will, our desire to decompose things, complex software applications into smaller units that have independent responsibilities.
It's an old idea.
It's like something that we've always tried to do.
Here you are comparing it to component-based software, but people often compare this to service-oriented architecture.
Yeah, and the SOA idea kind of, I think of all that of the component-based idea.
Let me give you, Fowler kind of doesn't like the comparison with SOA.
And he puts the reason for him to dismiss SOA as like a good point of comparison is because of the role of the enterprise service boss.
He's like this messaging system that you use in SOA has so much responsibility.
And that's not what we want with microservices.
He famously calls this smart endpoints and dumb pipes.
Let me read to you a couple paragraphs from his essay.
"When building communication structures between different processes," Fowler writes, "we've seen many products and approaches that stress putting significant smarts into the communication mechanism itself."
Good example of this is the enterprise service bus, where ESB products often include sophisticated facilities for message routing and choreography and transformation and applying business rules.
The microservice community favors an alternate approach, smart endpoints and dumb pipes.
Applications built from microservices aimed to be as decoupled and as cohesive as possible.
They own their own domain logic and act more as filters in the classical UNIX sense.
Receiving a request, applying logic as appropriate, producing a response.
These are choreographed using simple rest-ish protocols rather than complex protocols, such as WS choreography or BPEL or orchestration by a central tool.
What do you think about this rejection by Fowler of the comparison with the SOA because of these service buses?
So I think this goes back a little bit to my smart alecky comment about microservices being an application of architecture.
It's an architectural style.
So I think when people were doing component-based stuff and later SOA-type stuff, the idea was that building the service was the easy part.
And the architecture was this thing I'm going to sell you, which is this way that you tie the components together.
That's the architecture.
And maybe that's not a good thing.
Maybe those things you could complain about those architectures.
But it was an architecture.
Whereas I feel like what Fowler is saying here is microservices don't really have any specification for how they communicate.
That's pretty much up to you.
But when I see the wrong way to do it, I will let you know.
Yes.
Yeah.
But when I find a way that I can write a book that I can sell or give seminars on, I will speak up on that.
Hey, it's Nietzsche all over again.
I distrust all systematizers.
Okay.
I know what feels right.
Here's what's funny to me about this Fowler quote.
And I'm curious what you think about this.
He's saying they should be as decoupled and as cohesive as possible.
That sounds great.
They own their own domain logic and act more as filters.
And I have a little bit of a filters.
Okay.
They're choreographed using simple rest-ish protocols rather than complex protocols or orchestration by a central tool.
And here's there's this light bulb in my mind like, wait a minute.
What about things like the sagas pattern where we have a central orchestrator or choreography by events?
It feels like we're contrasting with SOA, an enterprise service bus.
But we're sort of re, we've reinvented a lot of those architectures to apply them in these complex places, complex fleet of services where they need to do things like transactions over shared data.
Right?
Yeah.
I mean, we have people have invented these approaches.
You've either got something centralized that sort of helps these things work in concert or you're passing messages around and hoping that things are picking them up and the latter is typically called choreography.
Okay.
Right.
Yeah.
What are the two approaches?
Orchestration and choreography.
We use both for the first sagas pattern in particular.
So, you know, we've tried both of these and sometimes both of them at the same time.
Whether we, whether we liked it or not.
And I think they're fine, but I think it's disingenuous to say that's simpler than a message bus.
It's certainly simpler to say, you know, my service has its own logic and itself contained and how you tie them together is up to you.
But I don't think these things that people have invented to make microservices work together are necessarily simpler than what came before.
If you have a whole bunch of things and they're all just using Kafka to communicate, Kafka, I don't know if it's necessarily simpler than an enterprise service bus, but it doesn't have a lot.
It doesn't have a whole bunch of different, well, I doubted what I was saying.
I was going to say it doesn't have a whole bunch of different responsibilities, but then I realized, well, some people will use it as a database.
So that's a gnarly contrast with what I'm saying.
Well, let's talk instead about a lot of engineers reach for microservices these days.
And it's common to fall into certain traps.
And I think what you're saying ultimately is you might feel as a software engineer, oh, I should be doing microservices here.
It'll reduce complexity.
I'll be able to scale this thing independently and I'll have this one team work on it.
And that sounds great.
I just, my responsibilities are that thing.
I can hold the whole piece of software in my head.
But your criticism, which I think is cogent is when we are having microservices described to us, there's no broader architectural framework that's presented from the start.
It's kind of like you're on your own, bring your own architecture.
And so what can happen as a result is people fall into something that has been named the distributed modelist trap.
So I want to break up this huge application into smaller services with separate responsibilities.
And there are ways I could do that that are significantly worse than just having a monolith.
And that would be the distributed monolith.
So the first thing that occurs to me is the point you already raised is how do I separate stuff?
If you can't reasonably decompose a module monolith into modules, your chances of successfully like drawing boundaries between bounded contacts are probably pretty low, right?
Like you got to be pretty damn good at organizing the big thing to be able to go, "Oh, there's some lines I can use to separate into smaller pieces."
Does this, what do you think about this criticism?
I think it's still at this stage in 2024 doing this as an art.
There's not a real science to it, which I guess is my problem.
I mean, there's never really been a science to getting modularization right.
There's rules of thumb and there's some classic work on how to decompose things going back to the 60s and 70s.
But I think they're still saying this thing should have a singular purpose, but then being able to draw a completely airtight box around that, the stuff that accomplishes that purpose, I think is still very difficult to do.
And this goes back to, in that previous quote where you were quoting Fowler, he was saying that the services should be as cohesive as possible and decoupled as possible.
This is a debate that's been going back to at least the 1970s.
Jordan Constantine in the 1970s has brought up this idea of cohesion versus coupling.
It's a fundamental idea of software, regardless of whether you're doing microservices or monoliths.
And so I don't really see that as being something that microservices solved.
I don't.
It's just, it's a way of doing it, I confess, but I don't necessarily think that it's something that's unique to microservices or that can't be accomplished without microservices.
Interesting.
So it's hard to define what the single purpose is, and therefore it's hard to achieve truly decoupled or loosely coupled services.
One big problem that happens a lot in the distributed monolith trap is the shared database.
If you read Sam Newman's book, he talks a lot about every microservices is just sort of a rule at this point.
Every microservice has its own data store.
They don't share data.
And the compromise that comes out of that is you're probably going to duplicate a lot of your data.
If I've got service A that's interested in knowing things about products and service B is interested in knowing things about products, probably the least fragile way to build that is so that service A and service B, they both have their own data stores and they both store data about products.
And as an engineer, you often want to respond like, wait a minute, now I have to update it in two places.
That kind of sucks.
And so the cheat is to make a central database where they can both look it up.
But now, okay, maybe a request comes in a service A and it needs to look up some service, some product information.
So it immediately sends a request over this product thing and service B does the same.
And now they share fragility, right?
The thing that tells them about the products, if it goes down, service A and B go down.
So that's a problem.
And that's what people describe as the distributed monolith trap.
These things are slower because I have to send out a request over to here to produce any work.
And if that thing breaks or changes, I'm going to break.
And this other thing is going to break.
So now here's what's annoying.
I don't have to just update one code base.
I got to update three.
If I want to fix the products thing, I got to fix service A and service B.
This is lame.
So that's the distributed monolith trap.
The real thing about microservices, I think, you have to commit to separate data stores.
You have to commit to the compromise of duplicating data.
And then you have to reckon with the idea that you now have distributed data.
You don't have shared immediately consistent data.
That's not easy.
Yeah, this has probably been my biggest issue with microservices over the years, probably because I'm kind of a database guy.
So there's something appealing about the simplicity of this service, one service, one database idea.
I confess immediately that is appealing.
But it also means that you give up things like integrity constraints, which I think are useful.
I might accidentally reference and identify or own by your service.
And maybe you deleted that, and I had no idea.
Yeah, you know, or there's, frequently you end up tying something in a database to a user or a customer.
And now you either have to have a separate service that with its own database, you communicate with to get user information.
Or you just have to totally give up the idea of having any sort of integrity constraints on your user database.
And I know there's ways that people have devised to deal with these ideas, but it's still something that kind of I'm not totally satisfied with in the microservice world.
And user databases and interesting examples, well, because you got PAI in that, right?
How many different places do you want to put that PAI for talking about separate data stores and duplicating data kind of sucks to put somebody's name and birthday and bank account information and social security number in all these different places.
That'd be lame.
Fowler talks about how one of the things with microservices, and I think this is part of the distributed monolith trap as well, is that you have to quote design for failure.
I'm going to give you another quote from Fowler's piece.
He writes, "A consequence of using services as components is that applications need to be designed so that they can tolerate the failure of services.
Any service call could fail due to unavailability of the supplier.
The client has to respond to this as gracefully as possible.
This is a disadvantage compared to a monolithic design as it introduces additional complexity to handle it.
The consequence is that microservices teams constantly reflect on how service failures affect the user experience."
I think he's right on here, and I've seen this appear in a couple of negative ways.
The distributed monolith trap is where people just do like, "Oh, I'm going to do this distributed function call here," and it always seems to work.
So I'm not going to worry about it failing.
And now suddenly I've got service A calling service B, and service B stops responding, and service A fails.
Now I've got two services responding or failing in the exact same condition.
That sounds like one service.
It's really joined together.
That's a distributed monolith right there, right?
I think this idea too is hardly new.
We once read that '90s paper that came out of Sun microsystems where they talked about how distributed objects is probably not a thing that's ever going to work because people don't understand the issues with distributed systems and how they fail and the timing and so forth.
This is another thing where it seems like you really have to understand, I think, if the complexity of this ads is worth it when you go this route.
I don't know that a lot of people do, and I think we've seen this in practice where you have one service that makes an asynchronous call to another service, and it's virtually impossible to detect if that call failed because asynchronous call says, "Okay, I'll do that."
And so you end up with these situations where you either need to pull something to find out if it worked or you have to start passing messages back to the thing that made the call.
It's not clear to me that that complexity is always worth the cost of what you gain by doing microservices.
Two comments on that.
One, one of the things that appeals to me about microservices is that you level up your function calls into the realm of distributed systems.
Distributed systems are way more fun, my friend.
Sorry, a little bit sarcastic there.
I have worked with people who are like, "Yeah, we'll just call it the service," and I'm like, "Wait a minute.
That's a distributed function call."
And they're like, "Yeah, it's fine."
I'm like, "No, it really doesn't feel fine to me.
It feels like we have to reckon with the fact that this is fragile, this is slower, this is there, you're adding complexity."
And it's not easy to just duct tape on failure handling, right?
So Fowler says, "Design for failure, but let's say, for example, I make a call and I know it can fail.
So what do I do?
I retry it.
Okay, that's probably not a great solution.
You can get into really complex problems.
You could produce things like the thundering herd problem, which I always think is such a great descriptive name for a thing.
But the idea is if I start retrying against a service that's gone down and maybe I've got a collection of services that are retrying, as soon as that service comes back up, all my retries will suddenly connect successfully and that's a thundering herd because it'll take that system right down again."
So these are things you have to consider.
That's pretty complex.
I think another bad pattern, I hate to be the guy that says you're doing this wrong, but I think another bad pattern that you often see is that people will build microservices and then they will treat them like code modules.
So service A will make a call into service B and then service B will make a call back to service A and you end up with these crossing lines.
Loops potentially, yeah.
I think it's fine.
I know you don't like it, but I think it's okay if a microservice calls another microservice as long as there's not some expectation that it needs to know what that second microservice is going to accomplish.
Yeah, I guess it's not that I don't like it.
It's like I build services that have to talk to third parties all the time.
Can I treat one of our own companies services as a third party service?
Does it make sense to do that?
Okay.
Can I know very little about what that thing's doing?
Can I be resilient in the case of failure?
Okay, that sounds cool, but most, and there's actually a lot of blog posts and talks about this, most of people who talk about the distributed monolith trap, there was one that was going around a couple months ago that I saw people pass around.
It's called how engineers can accidentally create distributed monoliths.
It's pretty short and concise.
It's a good description of these types of problems.
The problems described as too much tight coupling.
You've got communication dependencies.
You've got shared databases.
Suggestions people often make to fix this stuff are use the right bounded contexts.
Okay, so now we're talking about like, well, it should be more obvious how to break things up.
All right.
No shared data stores.
That's a hard and fast rule.
We can do that.
Async communication and event-driven architecture.
Very common recommendations for making these things more resilient, making them less like distributed monoliths.
Now, you just mentioned async.
So async and event-driven.
Is that going to solve our problem?
Do you think?
Does that count as an architecture?
It does kind of an architecture.
And I think at this point, maybe it's sort of the microservices architecture.
I kind of hate to make anything canonical, but it seems to be the way that most people are doing things now.
But even there, I think there are different flavors of it.
There's the case where you're doing asynchronous communication, but you really don't care what happens downstream.
Fire and forget.
Yeah.
And then there's cases where you're doing it because you're really trying to accomplish some sort of distributed transaction.
And you really need to know if the thing downstream fails because you might have to roll unravel stuff.
That's a sagas pattern typically.
Yeah.
So I think there's, it's not easy to do.
I mean, I think the, I guess the key point I'm trying to make with microservices is that microservices does not mean software is now simple.
Yeah.
A lot of people say it's a lot harder now.
There's actually been quite a backlash against microservices in the last, I would guess, five, six years.
I see this a lot on a place like Reddit where I read programming technology commentary and news and things.
On Reddit, there's a pretty widespread negative reaction when people start talking about microservices and saying, well, you should just make modular monoliths.
And this is a terrible idea.
And I have to say, and it's maybe unfair to cast all of the commentary I read on Reddit this way, but about five or six years ago, I used to see this commentary on Reddit all the time, which was like, you don't need Kubernetes.
It's so complicated and nobody's ever going to need that unless they need to scale to billions of things.
And often the thing I got frustrated with in this conversation was a nuance and people didn't distinguish between, I'm going to run this thing called Kubernetes, and I'm just going to pay a cloud service and I'm going to deploy stuff into it.
And I often wanted to, I didn't wait in the discussion, but I often wanted to say, wow, you guys, I'm using hosted Kubernetes and it is so freaking easy to deploy stuff.
And the amount of knowledge required to deploy stuff is probably equivalent to the amount of knowledge that required before when I was just hacking together auto scaling groups and junk like that.
And I've thrown all that away for this generic Kubernetes interface, which thousands of people are using.
Anyway, the reason why I give that example is it feels like these conversations are not often nuanced enough.
There's sophisticated people responding, but the tide is kind of turning against the idea of microservices.
There's a post you showed me from Twilio in 2018 and it's called Goodbye, Microservices, from Hundreds of Problem Children to One Superstar.
And then there's, of course, DHH, the Ruby on Rails originator, David Heinemeyer Hansen.
He writes even in an essay called Even Amazon Can't Make Sense of Serverless or Microservices.
This is a quote from DHH.
You showed me this post, but I'd seen it before.
Now, do we need caveats before we read a quote from him? -Turk, Turg, or what? -Turg, yeah, maybe.
All right, caveats.
This is a DHH quote.
Okay.
There is no endorsement of DHH opinions implied by this.
Here's what he says.
"The Prime Video Team at Amazon has published a rather remarkable case study on their decision to dump serverless microservices architecture and replace it with a monolith instead."
Now, side note from me, Eric here.
Serverless microservices are joined in this.
Anyway, continuing on with the quote, he says, "This saved them a staggering 90% on operating costs and simplified the system too."
And then he's talking about microservices.
Now, DHH, negative about cloud, once on-prem.
It's way cheaper.
He's right about that.
He's negative about serverless.
He's negative about Kubernetes.
Negative about a lot of stuff.
He's pro about Rails, this thing that he wrote.
He writes about microservices, "As with many good ideas, this pattern turned toxic as soon as it was adopted outside its original context and wreaked havoc once it got pushed into the internals of single application architectures."
That's how we got microservices.
He continues, "In many ways, microservice is a zombie architecture, another strain of an intellectual contagion that just refuses to die.
It's been eating brains since the dark days of J2EE.
Remote server beans, anyone, through the WS Death Star nonsense and now in the form of microservices and serverless."
Okay, so that's the DHH quote.
There's a lot of like conflation and very strong opinions and not a lot of reference there.
I think he's conflating some things.
What do you think about this quote?
It's a little much, but as I was saying earlier, I do think that a lot of what's encompassed in microservices does go back to distributed objects and SOA and component-based software.
I agree with the idea that this goes back a ways.
I think the question of whether or not it's a net good or if it's bad for the industry is hard.
I don't really agree with his conclusion, I guess is what I'm trying to say.
I feel like you start off where your entire program is run in one process and then you try to run it in two processes and now things are too complicated.
Because you're trying to distribute systems, right?
Anytime you are running your program outside of one process, stuff gets complicated and people will start arguing about whether or not that's a good way to do it.
I guess my point to my rant here is that there's really no science to this stuff.
There's people who managed to make decent applications as monoliths and people who managed to make decent applications as microservices, but there's not a formula you can follow that's going to make one of those things good and another one bad.
To your point about small monoliths, my greatest success with small services has been when I'm like, "Can I make this like a little monolith?
Can I just make it so that it runs on its own?
It doesn't care about what any other service does."
Those are the easiest to reason about.
They just run and run and run the least most fault tolerant.
They don't care, they're just out there doing their thing.
You could deploy these things and they'll run for years.
I think there's kernels of truth in what DHH is saying, but yeah, there's a lot of...
He's exaggerating a little bit, but he's also linking things that I've seen people link that I don't necessarily like to link myself.
He's linking serverless and microservices.
That a little bit has to do with the success of AWS marketing.
When they released Lambda in 2015, I worked with somebody at that time.
I remember watching this person very excited about AWS Lambda, deploying every single rest endpoint as a separate Lambda.
The amount of work they had to go through to deploy a single one of these things, I just looked at it and I was like, "That is a nightmare.
That's just complete madness.
It's like a zoo, a mortgage board of functions."
I was like, "This is really unmanageable.
Why do you want to do this?"
This is going to sound like an exaggeration.
This person who I worked with at the time said, and I remember this, they said, "Because microservices."
That was all they said.
I was like, "What do you mean?
Because...
Why are we doing this?"
They were like, "Because microservices."
That was their response.
That was a complete response they gave to me when I was raising technical objections to this.
You just don't get the lifestyle, man.
Again, I have worked with people who just will say, "I prefer this smaller."
That often doesn't feel like enough for me.
Is there any science behind this?
Is it all based on gut and intuition?
You brought to me a paper from IEEE 2022 called "Monolithic vs.
Microservice Architecture, a Performance and Scalability Evaluation."
They're trying to put a little bit of science behind it.
They say, "A bunch of small businesses are doing these microservices things, and they come with significant trade-offs, and they have bulleted lists with citations.
I'm going to read their bulleted lists."
This comes from the paper.
"These are bullets.
Identifying optimal microservice boundaries."
This is a hard thing we've already talked about.
"Orchestration of complex services.
Maintaining data consistency and transaction management across microservices.
The difficulty in understanding the system holistically increased consumption of computing resources."
This is a thing you and I haven't talked about.
You're probably going to deploy more cloud stuff.
Finally, for small-scale systems, these people who wrote this paper write, "These challenges may outweigh the benefits."
That seems like a pretty reasonable conclusion.
Pretty good set of bullets.
"Are you cool with these significant trade-offs?
If you are, go for it."
I guess I don't want to be in these engineering discussions where we're not talking about these trade-offs, where we're talking about what we prefer.
The paper's authors, big companies started doing this thing.
This isn't a quote, I'm just sort of paraphrasing.
They wanted to do it to address pain points around scaling.
Small companies started doing it because they think it will make things easier to manage.
Again, I'm summarizing what they said.
Big companies started doing it.
Small companies copied them.
They thought, "Well, this will be easier."
They write in this paper, because there's not a lot of research on this field, "Shifting towards microservices by small companies is often based on intuition rather than solid information."
I think that's where I've been frustrated by this conversation in the past.
What are we basing this on?
I'm guilty of this too, because often I have a gut-level feeling of, "Yeah, this should really be carved out and isolated."
I can see how it would be isolated.
One area of that for me is, "Hey, all of these services are interested in the same data."
Can we just put them all together?
I think this is cynical, I think, but I think there is a certain degree to which people just don't want to do the monolith, because it seems uncool now.
I really do think there's a fashion aspect to microservices that people don't want to admit.
Even the word monolith is like, "You said the bad word."
We have a product at my work, and I was like, "I always intended this thing to be monolithic."
People were like, "Oh, really?"
Even admitting that was a mistake.
In the paper, they build these benchmarks, which I got to feel like doesn't seem to me like a great way to evaluate microservices versus monoliths, because the reasons people give for these things are simplification.
They're talking about performance benchmarking.
They're saying, "Well, you may want to consider that your thing is going to be slower."
It's like, "Okay, but I think that's a trade-off a lot of people will make.
If it's simpler, easier to manage, less buggy, a little bit slower, okay, that's fine with me."
But they don't address that at all in the paper.
Anyway, at the end, they have this conclusion.
"A monolithic architecture seems to be a better choice for small, simple, small-sized systems."
There's that word again, small.
"They do not have to support a large number of concurrent users.
We hope that our findings will help companies avoid jumping into microservices simply because they are trendy, especially if better results can be obtained by scaling up their monoliths."
There you go, Mike.
The IEEE paper authors agree with you totally.
This is very trendy.
I have this image of the movie.
This is Spinal Tap where they get the 15-inch high version of Stonehenge.
That movie's probably too old for most people to understand that reference now.
I think I agree with this conclusion.
I don't know that it's going to make a lot of difference.
I think people want to do the new cool thing, even if it's not particularly the right thing for their organization.
What's the next thing to come?
Predict the future.
I think there probably ...
I know we've talked about the downsides of this too, but I think there probably is going to be a growth in serverless stuff in the coming years for a couple of reasons.
One is because I think I'm unclear also on what serverless microservice means.
That seems hard for me to grok because I think of a microservice as being something where I can have n number of replicas because I'm building it because I want that scaling.
You want to scale it to zero too, probably, right?
Yeah.
I think there are a lot of situations where this server function idea probably works for people.
I think it has the added benefit of the cloud providers are much better able to map those things onto their resources than they are.
If you're running a Kubernetes cluster, they have to go with what you are provisioning.
But if you're doing stuff serverless, they are really much more in control of how things get mapped onto servers and how things get spun up.
I really think that's going to be something that is hard to avoid as time goes by just because computing is so ubiquitous and it's so energy intensive.
People probably can't just continue to build data centers larger and larger data centers forever.
That's an interesting point.
I've said this before, but the thing I always want is the Kubernetes APIs on top of serverless.
I know this exists in various forms.
I know that there are cloud providers who offer things like this, but I want to deploy using Kubernetes APIs.
I want to scale to zero when there's no traffic and scale up using, whatever.
I don't care about the machines underneath.
Someday it'll come.
All right, my friend.
I think we have covered microservices versus monoliths, the debate.
I don't think we've come down too hard in one way or another.
I feel like we've done a good job of talking about the pitfalls.
Are you going to give me a hard time the next time I say, "No, I want to break this out into a separate thing"?
I kind of probably advocate for mega services going forward.
I think we should take of all our existing monoliths and just make them into one big thing.
This sounds like a Transformers metaphor.
Yeah, Transformers like the robots that turn into trucks, not Transformers like LLMs.
GPT or Transformers like in Haskell.
All right, that's enough nerdery.
This has been Picture Me Coding with Eric Aker and Mike Moll.
Thanks for joining us again this week.
Mike, it was a good time.
We'll see you next week.
Thanks.
See you next time.
Bye-bye.
Bye.