Transcription
um I think microservices are technical debt. I think everyone to a certain extent makes a distributed monolith. I'm one of these people who thinks that Go is a good programming language. A week ago, I made a video talking about a blog post that DoorDash posted where they discussed transitioning from a monolith over to a microservices architecture. So they had a Python monolith and they split it into microservices. It's better for a team to own a microservice because it can be deployed independently. And one of the original authors of that post, who's an engineering leader over at DoorDash, his name is Matt, he actually saw that video. And so I got to sit down and actually discuss microservices, and he had actually quite a lot of interesting hot takes. And I definitely learned a lot just kind of hearing his experience over like the last couple decades with microservices. And I think you'll learn a lot from it too. It's just a Google Meet. Like, the footage itself is just me and him in a Google Meet, but I don't think you guys care about that. I know you guys probably care more about the substantive stuff in the video. So I think it's definitely worth your time. Um, you know, I'm just one person, I don't speak for the for the company, but I can tell you how the company is thinking about these things. And it has changed since we wrote that blog post. I think there are some topics about microservices that are that are really interesting. That if you're if you're curious about this sort of thing, like this is this is like there's some tricky bits in here that that I think people should talk more about. So what I think the the first thing you should start with is really why, why would you make a microservice? But like, so if I already asked ask you like, just in you, in your own, regardless of what I'm doing, I don't know, why do you think someone should ever make a microservice?
Yeah, I think that's a good question. So it kind of takes me back to just like, what exactly is scaling? And so when I was kind of reading the DoorDash post, I initially thought, well, if they got this far with like a pretty large monolith, which of course, like I've never gotten to the point where I'm scaling a monolith to a very high degree, uh, nor have I gotten to like that cusp where it's like, okay, well, this is the line where if you jump over that, that's the point where microservices are worth it. And if if you go to the other end of that line, maybe you just want to stay away from them. And I guess maybe this is what you're getting at, where people think that line is is maybe changing over time. And I think for many companies, I'm sure it is worth it. My short experience at Google made me realize that, well, if they have all this tooling already set up, and they have like a large team of dedicated SREs that are handling all of this, it's probably worth it at that point to, you know, stick with microservices. There's really no need to simplify like the architecture, cuz we really didn't have to worry about those kind of issues, like those latency things. All that was abstracted away from us. And from that perspective, I think it's, Google has very mature tooling. You know, they've been they've been at this for longer than basically anybody. And so you would sort of expect that their stuff works really well. Like that's, I guess you shouldn't be too surprising. But also, you probably can't take what happens at Google and right infer too much about how to like make that be advice for anyone else. Um, but so I'm gonna, I I really, really wanted to stick to that to the like to the why though, because I think it's super interesting. So like, why would you take your monolithic application, doesn't really matter what language it's written in, where there's a single deployable artifact, like one big binary, one big ball of Python code, like one, you know, whatever you know language you write it in, but it's like one thing inside of it. The modules talk to each other by making function calls. And when you want to change it, you just deploy the whole thing, right? The monolith, right? So like, what would make you ever want to do a microservice? Or I hate the word microservice, honestly. Just what would ever want you to introduce the idea of making gRPCs or RPCs network calls instead of function calls? And I, I mean, I so I think that the answer usually works out like this. You're cruising along in your monolith and everything's fine. And then your company, you know, starts to get bigger, you know, your development team starts to get bigger, your your maybe your user base gets bigger. But like the the the scaling of the traffic is not, I don't think an issue. I think it's often cited as a reason to do services. I don't I don't think it should be. Um, if it is, there's probably something very specific about that environment. But I, there are very high-scale monoliths out there. I think it's that's definitely like possible. But anyway, um, what probably starts to happen is you have a lot of people all while work on the same thing. Then they start stepping on each other. Not while writing the code, but while rolling it out. So you got to roll it out. You cannot just flip the switch. And in this day and age, you never turn your software off. So like traditional software engineering texts, you know, they're all like maintenance windows or whatever, you know, what I mean? It's like not of this era, right? So our software, you can never turn off. And in a world where you can never turn it off, and you've got like maybe global reach and global audience, you're going to be making changes slowly. So like, developer writes code, it rolls out slowly for a day or so, maybe some hours, but not seconds, you know what I mean? Ain't no seconds, right? Well, the problem now is if you, what if you, if you have one developer or five developers, it's probably okay. It takes like four hours to do a deploy. But if you have 100 developers, now boy, they're probably gonna like start stepping on each other where like, oh, there's already a to plan away. So then you go, okay, we'll do a release train. Everybody get on the train. All the want to go out, they all go out together. But now what happens if one of them was bad? If you ship a bug, you got to roll everybody's change back. And I think this is the reason to do services is that you have a large engineering team and people are stepping on each other because you're changing it a lot. I I think you could you can imagine other examples of things like why it would be worth talking over the network, like maybe specialized hardware, like you're doing GPU inference, you know, ML inference, or you've got some other larger memory data structure, like a like a like a map, you know, you're you're computing ETAs, right? And so you've got a bunch of bunch of road vectors in in in memory, you know, graph, maybe you'll need a handful of those, right? And then it would be silly to embed that in the monolith, like that big in memory data structure.
Yeah, could be. But like, in terms of the microservices where everyone's like, I'm gonna move independently, like, I I think that's what forces you into that. Would you would you agree with that?
Yeah, I think I would. And of course, like, you have much more experience than me in this regard, but I think that's definitely the case, at least in my experience. So you mentioned like, why would you want to make RPC calls from microservices? That kind of reminds me that it's not exclusive from the perspective of like, back-end development, for example. Um, there was an application, Google Cloud itself, the front end for that is just one really big single page application. And it started out as that. And so there there's not RPCs being invoked like from those pages to each other. They kind of actually realize the exact same thing. This single page application, when there's dozens of services on Google Cloud, there's thousands of developers working on it. And they ran into the same problem. If you're going to be deploying it, one team is going to break the other team. And you can't really do anything about that. You're going to have to wait days, weeks. And so they did something very interesting. And I'm not sure exactly how they did it, but they actually made that single page application deployable in independent units. And it was all a matter of like, developer productivity. It had nothing to do with the scale. I mean, it's a single page application, it's going to be served the same way regardless, and it's going to hit the same backend endpoints.
Yeah, I think that's exactly right. That in my limited experience, I think I would agree with that as well.
Yeah, yeah. Okay, cool. So so I I think that is actually like, that's like, you just pointed out as an interesting way of saying, well, it, that's not necessarily doing services, but they found a way to modularize it, to break it up, so people aren't stepping on each other. And, you know, this, this kind of, there are different approaches depending on what it is, the thing that you're deploying. But but but somehow the issue of if you got too many people contributing to the same thing, and you have to deploy it slowly, that's what makes you want to split it out in services.
Okay, cool. I can tell you that DoorDash did not have the luxury of this kind of careful analysis about thinking about like, oh, how should we do our thing. Uh, so this is before I joined, but they had the pandemic. And all of a sudden, everyone was like, well, I can't go out. Um, I have to order food. And so all of a sudden DoorDash had way more traffic than they had before. And more, and you know, people needed bug fixes, and new restaurants wanted on board, and just like all the stuff, right? So the the development velocity needed to increase dramatically. And so they hired a bunch of people. And I eventually was one of them. And, um, but we were just stepping on each other like crazy, you know, like, it was not, it was not good. And the microservices, like, kind of effort at DoorDash started with some people just being very practical, going like, well, I've never done microservices before, but I am who works here. So like, we gotta, I'll just do the best I could do, right? And they started, you know, figuring it out. And, you know, kind of kept learning, like better ways to do it, better ways to do it. We learned a ton. And I would say, like, some surprising things that I think that that I learned about this is like, I actually think I think I've, I've been fond of saying this to to my to my colleagues, who who all kind of groan when I say it now, but, um, I think microservices are technical debt. And I say that intentionally because in in that, I do think that they help you move faster at first. I think if you're, you're you got a bunch of code running one place, and somebody says, you know what, why don't you just, I'm gonna write some code over here, you just call me with a thing for a time. That does help that one person, that one team move faster. Like they didn't have to get involved in this whole team's release process and their development, whatever they're just like, I wrote my code and I got it working. Now just call me over RPC. Like, it actually did make it faster for that team for that one thing. But the problem is now that this thing is running, it's part of the call graph. You, it has to be up, right? So I know a lot of a lot of microservices theory talks about like loose coupling and oh, what about fallbacks and does everything have to be up? And if everything has to be up, then you've made a distributed monolith. And that may be true. And it's kind of like not an useful thing to say, I think because like, I think everyone to a certain extent makes a distributed monolith, unless you really aggressively do fault injection, like really aggressively. I think you, you have a distributed. Most people have a distributed monolith, whether they realize it or not, because they probably don't actually know what will happen if their things slowly grind down to a, you know, a much lower performance and everything stacks up behind them, or, you know, just all kinds of different failure modes. But okay, it's nice ideal. None of the companies that I've worked for have ever made anything other than a distributed monolith, either. Like all the things have to be up. They just have to be up. And so you could say, well, you shouldn't do microservices. And maybe maybe you shouldn't. But they are technical debt. They helped people move faster for a time. If there's one, if there's one thing that I think that that I wish people would change their thinking around, it's that idea because it's not like it's black and white. It's not like, oh, microservices are bad. Like, you've got something in exchange for for your debt, right? Like you borrowed against someone else's productivity in the future. And to be clear, the productivity that you're borrowing against is someone else later needs to come to you and say, oh, we have a feature that needs a change to services A, B, and C. And first, we got to roll out a change to B. We got to get that thing rolled out. Now we got to roll out a change to B. And now we got to roll out a change to A. Now we got to make sure that the whole thing works. And and none of those changes got rolled back. And then later, if you're lucky, we can go back and say, hey, B, you can clean up that code and do a release just to clean up the code. C, you can do it. B, you can do it. But what we find is there's very little incentive to clean up that old code. And it, it just has a way of like making certain kinds of changes not only both expensive because you had to do like six deployments there to make one change, you had to do six deployments, it's crazy. But also it tends sociologically, like it, my my colleague Chris Mel John, uh, has this phrase, uh, that he where he he calls microservices a socio-technical problem. And I think that's a really good way of putting it. It's like, it's not purely, if it was purely technical, you would just say like, well, do a good design, do a different design. But like, there are people motivation, someone wants to get, you know, this product shipped right away. And they don't care what happens next year, they just want to ship it right now.
Kind of what you're saying is that it's like a people problem? It's like maybe a management problem or just like an organizational problem?
Um, I would definitely agree with that. In my experience, we had like a microservice that belonged to a different team originally. And then so we kind of inherited it at one point. And then you kind of mentioned like, as the number of microservices grow, it's kind of technical debt. Like there could be consolidation. Like, in hindsight, you look at it and it's like, well, these didn't need to be separate. You could consolidate them. And we even got to a point once where we had one service using a data store. And then we thought, well, rather than creating our own instance of that same data store for the second microservice, we could just reuse that same one. And so if they're reusing the same data store, well, then that's kind of feeling like a monolith. But you know, in that case, we were choosing to do the monolith to go faster. Actually, we're saving time by doing that. And then it kind of creates the complicated issue where it's like, you don't really know what it is anymore. And you're just optimizing for time.
Yeah, it's kind of like a really hairy problem. And I guess I don't know necessarily the solution to it. If everybody had infinite time, you'd kind of clean everything up. But you don't.
For sure, for sure, for sure. And you must realize, surely at this point, that the comment threads are going to explode with people saying that microservices should never share databases. Like, can you believe that? That like absolute just like sacrilege that you've committed there by having two services share the same database? Like, how do you live with yourself? I mean, it must, must be rough.
Um, yeah, I mean, dude, we did the same thing. I mean, like, the the early, the DoorDash early DoorDash micro, you know, microservice deployments were just like, migration is hard. And like, you want to make us like, literally copy the data out of this database into this other database, like, you know, so.
Um, but anyway, I I think the people, it's, I wouldn't say it's just a people problem. I I would think if if it was, we, I, I don't think we would have so many engineers having so many opinions and being being, you know, kind of wrestling with this challenge. I think it is, it's at the intersection of people, you know, people at work, and, you know, people like getting paid to make software, right? Um, and the software itself. And there is a technical component. It's like the software resists being changed by too many people too quickly, right? Like that's the technical problem. It's like, if you could find a way to safely let a thousand people change the same thing and just know that they weren't breaking each other, then you would probably let them do that, right? That's the technical problem. But and it's, but what we have is like, kind of somewhere in between. So you say like, well, if you can put your stuff on the other end of this RPC, then maybe we can start to reason about, okay, did, did your thing break, or did my thing break, etcetera. Even though you practice a call graph that like propagates error back, everyone on the call graph ends up getting paged, right? It's super hard to say like, oh, the reason I'm sending back errors is because two services down started sending back errors. You just end up paging everybody. And we had the exact same problem where we had like latency charts like within our UI. And if like the upstream service like increased latency, then we kind of get paged as well. And it was never our fault. Like it was always a false alarm. And then so you kind of get into the habit where it's like the boy who cried wolf. And it's like, every time you check it, there's nothing actually wrong. So then you get in the habit, but maybe if there's an actual issue, you're not going to double check it. And that's not a really good position either.
Yeah, that's right. That's right. Yeah. I, uh, I, I don't, I don't know how much time both of us have. But I sent you a couple of links here. One is to, uh, Chris Mel John's PhD thesis, which he did on microservices, um, and based on research that he did at DoorDash, which is where he talks about the sort of socio-technical problem. Um, I also, I also dropped you a link to a talk that I gave in 2016, that talks about, uh, where where I where I suggest what might come after microservices. There's there are a couple screen. That was when I worked at Uber. There are a couple screenshots in there of a tool that they built at Uber that is super cool. And I've never seen anything else like it that does try to tell you in an RPC call graph, whose fault is it? So like, if, if you're sending back errors, you're burning your SLO, you're doing, you know, whatever, like it's your service is in trouble. It's a, a tool that will tell you whose fault it really is. Usually, I think it's pretty cool.
Interesting. Yeah, it, I mean, I think it is possible to build tooling to make some of these microservices problems like less bad. I think people would be upset if I didn't ask this question. When it came to that migration, was it worth it to kind of go into the microservices direction? Or is it more complicated than that? In that it helped you initially, but now maybe you're kind of paying that tax, or have you already paid that tax and now, you know, it's just smooth sailing from here? What's kind of the situation right now?
No, I mean, it's, that's a really good question. Um, DoorDash had to do it, you know, they just, they couldn't, they couldn't move any faster with their monolith architecture. Theoretically possible with enough time, they could have re-architected is one separate monolith. And the the the driver, you know, assignment is different. Just you could you could imagine dividing it up into some chunks, right? It could have could have done that. They actually actually did do some of that. But but even so, it was actually still the same code because there's all this like shared code. And and the test suite was taking forever to run. And it was, you know, it needed it needed a major re-architecture. And they didn't have time, you know, they needed to add features, fix bugs, and do stuff. There, there was no time to re-architect the monolith. And like I said, you can move faster at first by breaking stuff out. Um, where are we now? Like, I don't know, we're kind of still in this like, there's no more monolith. Like monolith is monolith gone. And, you know, we have hundreds of services. 500? I think you need about like 100 to like place an order and get it delivered. I think that's about right. You know, what was it worth it? Like, of course, it was worth it because the the company was gonna just, the the monolith was grinding to its death, you know, it was like overwhelmed. That you couldn't fix. No one knew how to fix it in enough time. So like, it was worth it because we, you know, DoorDash still exists, right? Like, here we are. Had you know, had I joined the company sooner, I might have tried to steer us into some like slightly different directions. But like, you know, it, it solved the problem. Like, it, it made it so the the company, you know, could could keep growing. But at the same time, like, we learned just a ton, a ton, a ton about like, what are the hard parts about microservices? And yeah, you know, stuff that we talked about in the blog post. But it's, it's all that socio-technical problems, you know, it's like, oh, you want, like, we realize this problem, like, if everyone would just please upgrade their gRPC client, um, then we can fix this weird interaction that we have sometimes. But there's very little incentive for people to want to like, go upgrade their gRPC clients or pick, you know, pick your other library, right? So like, now you've got 500 individual things that are running some version of some set of dependencies defined by somebody somewhere. And then like, you want to say like, well, you, we really want you to go in and change your code to this, you know, the API is different. We need you to get down this new dependency. Like, it'd be really great if you did, you know, like, it's kind of hard to justify. If I were to give people advice, I would say, use as as few as possible, right? Like, are we stepping on each other? Okay, fine. Find a, like, split it out, then. And then like, that is, I think very reasonable. And not just, oh, by my domain-driven design ideas, the consumer service shouldn't know about the something something piece of data, therefore, it should be a separate service. Because what you have, I, I'll tell you a fun stat. Shoot, I wish I should have looked this up before. Um, okay, I'm going to get this a little wrong, but it's order of magnitude correct. Um, the average fan out when you make a request to the DoorDash, like front end, average fan out is you make about a thousand RPCs. And I think that might actually be too low. I think it's more than a thousand. But like, the reason is because of this domain principle, people are like, oh, well, I'm not the consumer profile service, so I shouldn't know about consumer profiles. So then like, you go through this call graph, and every step of the way, someone's like, oh, I need the consumer profile. So then they go get the consumer profile. And, you know, you can have caches and stuff, and that's fine. But like, if you, you make everything have to go out over the network, everything is really gonna end up going over the network, like, like to an absurd degree, you know, where where even simple things that you might think, like, oh, that maybe could that just be a library? And then someone will say, yeah, but where's the storage come from? And then you have all these philosophical arguments about how, what's the right way to do microservices. And next thing, you know, you have 500 services and a thousand way fan out on on average.
Yeah, that's really interesting. And honestly, I have one question for you. And maybe this will be a little bit, uh, controversial. But I think what you're saying kind of reminds me of how many times like programmers have this kind of like philosophy. They're kind of reading off like a Bible. And like everything has to be done this way. Like, you know, there are some interesting that people say, like, you know, when it comes to, let's say, like unit testing, or like object-oriented programming, which, you know, some people have like their opinions on. But obviously, like the context matters. Like, you could say that this is a principle and like, it shall never be broken. But if like the context of the problem is like dictating that, okay, well, the solution is just more simple to do it this way, or maybe we just don't need all these unit tests, or like the unit tests aren't actually helpful at all. You can pretend like they are, you can pretend like it's going to help you sleep better at night. And of course, I'm not against unit tests or anything like that. I have an application where I haven't written a single unit test. And it's a relatively small codebase. And I own it. I know every line of code in it. And so for that reason, I know 90% of the time when something's going to break, if I make a change, I'll manually test a few things. And to be honest, I, I do think it saved me time. Now, some people might say, well, that's that's dumb. And maybe it is. I don't know. Maybe I'll have a major outage in the future. But at the end of the day, it saved me, I would say at least 50% of the development time.
Yeah, okay. So yeah, your your overall question is, are there just these ideas that programmers have that that they stick to? They're not exactly sure why? And perhaps they stick to them at their detriment? Um, and the example you cited is is test 100%.
Um, yeah, a example of that is that, you know, the thing I talked about about like, oh, you have to have that as a separate service because that's how you do microservices. Um, testing is a fascinating topic. I am I I too am not against writing tests. They have saved me many times. Um, but, uh, tests have a curious way of making some changes harder because they kind of like solidify the way a thing works. And you might look at doing something and, you know, that it would be right to kind of refactor something, move it around. You're like, oh man, I'm gonna have to rewrite all these tests. And this is another socio-technical problem. But it like, it tends to have, like, if in in projects that have a lot of tests, it tends to encourage, uh, people to work around the fact that the they just want to keep the test suite working and not necessarily get the best architecture. Um, also test coverage. I, I am deeply frustrated with this as like a metric of performance because all that really matters is your assertions. Like you can have 100% coverage and just say assert one equals one, right at the end. You've covered all your code, good job. But there's no way to measure assertion quality. And I actually kind of wish there was because if there was a way, I think I would be on board with you should probably have some amount of, you know, tests that with quality assertions. But lacking any way of measuring the quality of your assertions, I think it's kind of silly to chase to chase test coverage numbers. But but we do it. It's my personal opinion. We of course say, oh, no, no, it's very important that you have test coverage. And it tends to be that people also when they're in there making their test, they tend to have good assertions, you know, but it's like, it's a little misleading. Seems like, but anyway, yeah, people have that. And it's really hard to, um, give people a framework for understanding when they should question these kind of dogmatic ideas. I, I actually don't know. All I know is I've been doing this for long enough that I just kind of have a sense of when I can get away with it. And, you know, and then people kind of look at me and they're like, Yeah, but isn't 80 better than 70% test coverage? You know, and we'll have those arguments. But I don't know, man. Yeah, it's this a huge problem. I think is that like, how do you know when this, you know, ideal is serving you or is actually hurting you? It's that problem.
How do you have any other like last minute like hot takes where you think the industry is just wrong about something or just a general trend that you've seen that's just like counterintuitive or just not helpful at all? How do you feel about object-oriented programming, I guess? Or or any other kind of, I don't know.
I mean, I, I think I'm, I'm one of these people who thinks that Go is a good programming language because it has fewer features and makes you think about your programs differently. Um, and it's somewhat somewhat controversial. But I, I actually think it is a, it's a wonderful, uh, language for a large team to collaborate around.
I think the YouTube audience is gonna agree with you on that. YouTube definitely loves Go.
Yeah, yeah. But I mean, it's that definitely gets me, gets me a lot of, uh, a lot of sort of heat discussions in the, you know, sort of professional software engineering, uh, community who are like, yes, but why not, you know, Java or Kotlin? And they're like, fine, fine, fine. You want some modern pro, modern compiled language, you should do Rust, you know, and all that's true. Um, but, you know, what here's my my final thing is, I actually think that it's a shame that the industry has not produced, uh, an an alternative that we say, uh, oh, monolith, obviously start, you make a Django or whatever, kind of thing, you start your company with, like, that's cool. And then when you break it out, you do, you do microservices. And then like, you read some, like ThoughtWorks books or or whatever, and you like, you get the the cool way of doing it. And I, I think it's, it's bad. I think I think we should build frameworks that offer a different set of trade-offs. Like this, this tradeoff of it's either all in the same thing, or it's in a million things. And you have to like design it explicitly around these assumptions that it's all in a one monolith, or it's always making network calls a over place. I think it's terrible. Like this industry, like should produce new abstractions, new frameworks. I don't, I don't know exactly what they are. We're, I'm actually working on one at DoorDash that's not done yet. And we'll see how well it works. But, you know, it was a huge battle to try to get it funded because everyone's like, but the rest of the industry is doing microservices. And I'm like, I know, but they're bad. I think we should better. I think we should do better as an industry. And, you know, so like Google has that thing called Service Weaver. I think that's an interesting step in this direction. It, it doesn't fully address the issues of like, you even if you write one program, you still might need to do like, interact with this whole RPC ecosystem. Um, but it's cool. I think it's a really cool project. But in general, I want the industry to do better. We should not have to pick between monolith and microservices. There should, there should be, there should be something in between.
I guess. Okay, last, last question, because I know people are going to want to know this. So do you have any advice for other programmers that are listening to this? Maybe they're in college, maybe they're working full-time, and they kind of want to follow in your footsteps and get really good at application development, backend development, and, you know, architecture design? What should they do? Are there blog posts? Are there books they should read? Should they come join you over at DoorDash? What should they do?
Well, I mean, that's certainly one way of doing it. I mean, I don't, here's the thing. I, I don't actually know. Like, I got super lucky and in my career, and that just I happened to be in the right place at some right times and, you know, met some people that gave me some opportunities. Um, I, I just, I don't know, man. I just write a lot of software. And I just don't, I, I don't, uh, I'm not settled or not satisfied with when someone says, ah, here's this library, like, just use it. Like, I always want to know what's in there. You know, I, I, I have a deep fear of dependent, like, I don't like run other people's code unless it's really important. And when and whenever someone says, hey, we're going to use this library, I'm like, all right, let's have a look. You know, and I, I want to like, like, read the dependencies and see what they do. Um, uh, man, I don't know. I just, it's very hard to replicate luck. But I, I just think like, if you, if you care about your craft, you care about like understanding like how stuff works, and just like what good looks like, and not necessarily getting sucked into these kind of dogmatic ideals, like we were talking about, you just like, what, like, good is contextual based on what kind of project you're working on. And I think it also evolves as the industry evolves, technology evolves, just, I don't know, figure, figure out how stuff works, just make, make software better.
I honestly completely agree. And I'm so grateful. Thank you so much for like joining us. And I'm so glad that you kind of said some of the things that I feel like if I were to say them, I might get in trouble. But, you know, now I got the credentials there. And I think like, most importantly, a lot of these are like open-ended things. Like there's no one right answer. And at the end of the day, you're just trying to create applications that work and that serve users. And the tech behind the scenes isn't, you know, the number one thing.
Yeah, so socio-technical problems. That's, that's how you should think about it. And you should think that you should, you should definitely think that microservices are technical debt. I mean, I just not satisfied with that. Let's, let's do better. Let's find a way to do better.