Check out a free preview of the full Introduction to Backend Architectures course
The "Monolithic Use Cases" Lesson is part of the full, Introduction to Backend Architectures course featured in this preview video. Here's what you'd learn in this lesson:
Erik discusses that monoliths are suitable for small-scale applications or startups where the application scope is clear and unlikely to drastically change or scale. He also addresses students' questions regarding scaling monoliths, security concerns, and sharing types between frontend and backend.
Transcript from the "Monolithic Use Cases" Lesson
[00:00:00]
>> Erik: Let's talk about use cases of monoliths, the first use case of monoliths is really small-scale applications, right? Given its simplicity, a monolithic architecture is often suitable for small-scale applications or startups where the application scope is clear and unlikely to drastically change or scale. I have a friend who is a founder who works on a lot of projects, and I think he's probably one of the few people I've ever met that have mastered creating monoliths and turning them into sellable products.
[00:00:30]
He can build fast, he can get his project across, and then he can immediately get buy-in for it and that's his goal on a lot of the projects that he works on, right? Monoliths are a great, great solution for that, right? If you go out the gate too fast with too much complexity, right?
[00:00:48]
You're gonna find yourself managing services way more than you're gonna find yourself actually making profit. And so especially early on, this is really where that whole term of like start out with a monolith really comes into play. Because more likely than not, you don't need to have distributed crazy systems as the first thing you do, maybe it might be helpful, right?
[00:01:13]
But seriously, if you can just build a monolith and get started, that's normally going to help you a lot more, and again, yeah.
>> Speaker 1: You mentioned earlier about flexibility, accommodating changes, new feature requests, sort of I have this new startup. I don't intend for it to not scale, are there any strategies that you've seen where I'm starting with a Monolith?
[00:01:40]
But I've sort of, encapsulated some of those boundaries such that I can turn it into distributed if needed and what might be some approaches to that?
>> Erik: Yeah, so we are gonna talk about that a little bit later in the evolution of an architecture. But, yeah, a good way of doing that is really trying to do the modular approach, but on a logical level, right?
[00:02:08]
Think about the shared logic between your controllers, right? Think about the things that they need to use outside of those controllers. And a good kind of approach I like to take is I like to design even the logic in a way where if I ever have to go like, okay, I want a service for this, I should be able to just separate that code.
[00:02:30]
It should almost be copy and paste to where I can copy out those files, wrap them in a new listener, and then bam, that's a new service, right? If you have a lot of complexity around the logic of those shared components, then that becomes harder to decouple. But you could very easily set up data structures in the way so that it's, again, just user data, just product data, just check out data.
[00:02:58]
And then when you get to a point where you're, okay, I want three services, all the user data goes over here, all the checkout stuff goes over here, all the processing data goes over here. And then they can exist as three different services that you scale individually. But it really comes down to you as a programmer thinking about how coupled your logic is to the other parts of your software that you're building.
[00:03:24]
And if you feel like that's going to happen like nesting functions, for example, right? Like, if you've got a bunch of different things happening in the same route, maybe that should be two routes, right? Maybe that should be three route, right? For example a sign-in flow, maybe a sign-in flow only needs to take care of this one thing and then you can off-board other things to other routes.
[00:03:49]
Don't do too much in one space, basically is what I'm trying to say. If you do too much in one specific space, it becomes harder to decouple those things and move them around. Does that answer your question?
>> Speaker 1: Yeah.
>> Erik: Cool, yeah.
>> Speaker 2: Are there higher potential security risks with monoliths since everything's all just kinda right there?
[00:04:11]
>> Erik: Right.
>> Speaker 2: You have to take extra measures to make sure things are protected and-
>> Erik: Yeah, absolutely, I mean, if you If you think about it, the monolith is your golden goose. It's the one thing that's bringing all traffic to your system, it's what you're managing everything with.
[00:04:28]
And so, yeah, I mean, it could be very possible that you could have an endpoint that is exposed, but doesn't even directly relate to what the vulnerability is. Just because it shares logic with the user data, or just because it shares logic with credit card lookups and stuff like that.
[00:04:48]
If that is attacked, the whole system could be compromised, yeah, absolutely. So, I think that is where, going back to the planning stage, you really have to start thinking about security concerns. How do you make sure that, for example, it's probably very common in monoliths to have public routes and secured routes in the sense of some are public, some session stores and stuff like that.
[00:05:15]
Yeah, you got to be good at that, you got to be able to be prepared that this route is secured, how do you secure routes? Is it easy to secure routes? What happens if it's not secured? Or even further, if it becomes compromised on a shell level at that point then, yeah, you're not in a good place at all.
[00:05:35]
So yeah, security definitely, I think becomes a lot more challenging when you have just a bunch of things going on at once, and you have to be considerate of all those things. So, again, that's where I would kind of go back to his question even as well if modularizing your code in a way where you have a good structure around securing off routes versus on off routes, right?
[00:05:57]
You have a good structure around how your configuration data is loaded or how the process runs and things like that, those definitely need to be considered, yeah, absolutely. Okay, so another use case, applications with simple, well-defined business processes. So, monolithic structure can be beneficial in scenarios where the business processes are simple and unlikely to require significant changes or additions.
[00:06:24]
A lot of what we're talking about here is just, you wanna implement something. You don't wanna spend a ton of time on it in figuring out how a design approach for it. But you really wanna make sure that it's at least solving the problem that you want, and making sure that it handles the scenario or the business processes that you need.
[00:06:43]
You don't have to necessarily, let's go distributed and have inter service communication. You could technically just create another monolith and put it next to the other monolith. Now you have two monoliths, but it's definitely a part of where you start saying like, okay, this monolith does this, this monolith does that.
[00:07:03]
And in that case, you're not really distributed, right? Because if one goes down, then it's still in that case, will probably be impacting most of your systems. But if you already know how to build a monolith, or you wanna start decoupling those things, you could effectively make two monoliths if you wanted.
[00:07:24]
And that's a design, services and monoliths are a bit different in their scope and what they focus on. But again, if you have two different things that you are like, a reason to have that separate operation, you could at least try to do that with multiple monoliths. And then high performance, where high performance is critical.
[00:07:48]
You will, nine times out of 10, always deal with performance issues with distribution, because there's more network latency, there's more hops required, and things like that. Going back to the bot example that I shared with you guys earlier, right? Not only does a lambda you know firing a bunch of time bad for cost but what is another thing that makes lambdas bad?
[00:08:11]
Does anyone know? What is it number one common things with lambdas that everyone deals with?
>> Speaker 3: Cold starts.
>> Erik: Cold starts, exactly, yeah, and so what can be tough is that you wanna be able to have a bot that responds under a millisecond or 5, 10 milliseconds. You're gonna be at the mercy of cold starts, you're gonna be at the mercy of whatever architecture you're using.
[00:08:36]
And so again, in this scenario, I could have a Twitch monolith and a discord monolith, but they both process and have high throughput and performance for the things that they want. Or I could join them together and have one big bot that processes all requests. But high performance, you cannot argue that a process just sitting there waiting to return a request is gonna be slower than like, something that requires multiple jumps, it's just gonna be faster.
[00:09:05]
It always will be, because you're not talking about the performance of network, you're just talking about the performance of the CPU and how fast it can process it, basically. So again, if you're in like real-time chat applications, stuff like that, that can really be a benefit to using a monolith for the specific type of processing that you're trying to do.
[00:09:27]
Because you're shifting network latency to compute latency and again, compute latency is always gonna be faster.
>> Speaker 3: You're sharing the same types between front-end and backend worth the increased complexity.
>> Erik: Okay, it sounds like somebody using TypeScript. [LAUGH] So, that really depends on how coupled you want your frontend to your backend, right?
[00:09:59]
Types become a logical change, which means that if I wanna update a type for both systems, I have to redeploy, right? Does that mean that that's a bad thing? No, because technically, again, if you are using typescript, which I'm not trying to pool on typescript, but if you are using typescript TypeScript, that's a valuable purpose of using it.
[00:10:20]
You have the same language in the frontend, the same language in the backend, and it becomes really easy to share those components. However, think about the changes you have to make, first off, you have to go to the library potentially and make your Enum change or whatever, right?
[00:10:35]
Then you have to go to the service, update that library, right? And make sure that that's got the latest and then you've got to deploy that, so now you've got two changes that need deploying. And then you have to go to the front-end and change that and then redeploy that as well.
[00:10:48]
And if anything happens with that, then you got to go back and restart the whole process all over again, right? In my mind, that is not decoupling, right? In my mind, that is just improving developer experience, which I would even argue is not really a great developer experience, because you have to update two or three things at least to be able to do it.
[00:11:12]
And on top of it, if you remove the library from the scenario, then which one is in control? Is it the back-end that's control of the types of the front-end and the front-end follows it? Or is it the front-end that controls the back-end and the back-end follows it, which gets deployed first?
[00:11:27]
Which gets deployed second? What happens if they're different, right? That becomes a really big challenge when talking about consistency you can get data consistency issues and things like that. So I think the goal that would absolutely be a monolithic approach versus a distributed service approach. Where, well, no, that becomes an end point and only that endpoint changes whenever you need instead of having to update code in multiple places.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops