DEV Community

Cover image for #DevDiscuss: Monoliths vs. Microservices
Erin Bensinger for The DEV Team

Posted on • Edited on

#DevDiscuss: Monoliths vs. Microservices

image created by Margaux Peltat for the Chilled Cow YouTube channel

Time for #DevDiscuss — right here on DEV 😎


Inspired by @lovepreetsingh's Top 7 post, tonight’s topic is...monoliths vs. microservices 🏗️

Questions:

  • Do you prefer working with monoliths or microservices?
  • What are the pros and cons of each approach, in your experience?
  • Which microservices patterns have you had the most (or least) success with?

Top comments (18)

Collapse
 
ianfoo profile image
ian molee

In many cases, microservices are a better organizational solution than they are a technical one. If you have lots of people working on a product, they likely make sense by offering teams autonomy in feature development, infrastructure requirements, and deployment. But until you reach this point, they add a wealth of complexity with only the promise of future returns that may or may not be realized.

A carefully developed monolith with attention paid to reasonable boundaries that can later be split off into individual services may be the ideal way to start, in my opinion. Maintaining this sort of discipline for any length of time is difficult as scope and staffing levels grow, though, and is likely why we see efforts start with an over-engineered set of services, or build what will become an unwieldy monolith needing substantial rework later to divide into smaller components.

Collapse
 
pacheco profile image
Thiago Pacheco

I don't think it is about preference, it is more about the problem that needs to be solved and the current constraints.

Microservices are great when dealing with an application that is big or bound to grow. In this case, microservices make separating responsibilities between teams more straightforward and allows parallel development. It also helps with small and isolated releases.
That is all great but it comes with its trade-offs.

  • The coordination between teams and services becomes harder to control.
    • Teams may build the same functionality replicated everywhere, documenting and sharing information becomes harder, defining a pattern to be followed by the whole company can be tricky.
  • Separating domains is also a difficult task at some point.
    • This may make you build unnecessary services or resources only to figure out later that they are not living where they would make more sense.
  • Dealing with distributed systems is hard, especially at scale.
    • Sharing code and libraries can be complicated.
    • Managing communication between services is also a hard task.

All of the problems above have solutions and workarounds, but they are still things you would need to keep in mind when working on a microservices architecutre.

I found that event-driven architecture is the most fun and rewarding architecture to work with when dealing with microservices, as it allows us to work on a fully decoupled application and execute services in total isolation during development (that is if you are able to successfully separate every context).

Monoliths on the other hand are the simplest approach and they should be the go-to choice when first starting to build an application. Starting with monoliths helps with developing and releasing a POC faster and it can even be that the simple monolith built may actually solve the problem, in that case, it prevents you from spending a lot of effort and energy thinking about a distributed system.
Monoliths are a great choice if your context is small, you don't have the need to separate the application in many chunks between teams and release small parts independently.

A strategy that is very helpful when working with Monoliths is using a Layered Architecture, as it is one of the most well-known architectures, has a lot of resources available about how to use it and is very simple to understand.

In the end, choosing the type of architecture for a system is all about trade-offs and it may vary a lot based on your context and problem.

Collapse
 
danielelkington profile image
Daniel Elkington

Microservices may be a good solution for very large applications with a large development team, but for most apps they just add unnecessary complexity. My team started migrating a monolith to microservices due to the hype, before quickly realizing that it led to too much complexity for our small developer team to handle. We had to backtrack and now have a well-structured, performant and understandable monolith.

Collapse
 
katafrakt profile image
Paweł Świątkowski

Everything you do "due to the hype" will have negative outcome. It doesn't have anything to do with microservices or not. I used service approach (not exactly micro-, but IIRC 7 of them) with a team of 3 devs and it worked well. Did not work at all as a monolith.

Collapse
 
heyjtk profile image
JTK

You can of course have badly organized, managed, and maintained monoliths and badly organized, managed, and maintained microservices. I will say the non-technical elements of microservices are as appealing to me as any. The ability to have several things in relative isolation that can be worked on without people tripping over each others has been a very nice workflow for me on several very different dev teams with very different needs

Collapse
 
prodbyola profile image
prodbyola • Edited

Great point JTK! As an architect, it always matter that I prepare for a "big day" even if it's a project we're starting small. Microservices don't look as complex to me as monolithic designs wherever scaling is a thing of concern. It just feel so natural to want to keep things well structured from the beginning even if I'm the only one working on it.

Collapse
 
heyjtk profile image
JTK

I'm with you, I'm comfortable enough in some cases starting microservices from the getgo left to my own devices. Although I try not to be dogmatic if there is some valid objection to going that route. I have not heard....too too many of those? Most places I go with monoliths it is just because the project started that way, most places I go with microservices its because they just started that way, haha.

Thread Thread
 
prodbyola profile image
prodbyola

Oh yes, open-mindedness is key! I've joined teams working on a monolith project and I wouldn't dare say "Oh, this is nonsense!" just because of the design pattern. No matter how difficult it is to manage, we have to consider the cost of redesigning...or whether the whole team is ready to catch up. However, I've been fortunate to be at the planning and make foundational decisions most times... and it has always paid off when I hand over, or when more people join in the project.

Collapse
 
fleker profile image
Nick

I prefer microservices. Monoliths can be easier to manage but building them is onerous and prone to update issues. You can't "just do" something without spending tons of CPU cycles and time.

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

I wholeheartedly disagree that microservices are an organizational solution for large teams. Sure, it is more obvious, but microservices bring a lot to the table. Being in my 2nd enterprise-level microservices project I think I can say that the potential for scaling is immense and so easy to put in practice that I sometimes scare myself with thoughts like "let's go spin up pods in prod, K8s will cover our backs!".

But not only that. Database splitting makes it easy to harness the power of multiple databases and database engines. Last but not least, if you implement a queue (which normally is the case), you can stop catering HTTP endpoints for downstream consumers as they can now go serve themselves by listening to the queue.

It is also quite straightforward to migrate a monolith. In a very small nutshell, you spin up a gateway and then you start re-routing little pieces over time from the monolith server into microservices. While you do this, you can have a compatibility microservice mirroring the new database's data over to your old database, and nobody has to notice or even know.

It is also not true that you need a large team to work with microservices. Yes, with a larger team is easier, and yes, some companies are so luxurious that they do have 1 team per microservice. My team is poor and out of luxury, so we do all microservices. What I did was to architect a common architecture that serves as template for all MS's and then maintain the common code in (usually 4) nugets (because we do .Net).

If you can afford me as architect, I'll transform your monolith into a microservices solution that can be maintained by 1 team. 😄

Collapse
 
charliesay profile image
Charlie Say

I think this is totally subjective and a million dollar question!

I have worked with many companies and current company where monoliths just make sense. Since my team is a backend team and not too familiar with front-end, having a monolith is easier it allows us to bundle everything together and allows us to understand how things work together from front to back WAY easier. However in my years I would think :

Pros:

  1. Simpler to develop, since all of the code is in a single codebase
  2. Easier to understand, since all of the code is in one place
  3. Tends to be easier to deploy, since all of the code is packaged together

Cons:

  1. Can be more difficult to scale, since the entire application must be deployed in order to add new features or make changes
  2. Can be more difficult to maintain, since changes to one part of the application can potentially affect the entire system
  3. Can be more inflexible, since it can be difficult to make changes or add new features without redeploying the entire application

However, I am biased slightly about micro-services (positively). Because each service is self-contained and communicates with other services through well-defined interfaces, it can be easier to scale and maintain a microservices-based application. Since we are heavily invested in AWS and follow an API Gateway Pattern, I can see a trend towards us using micro-services more. Since the almost module like architecture allows debugging and finding errors SO much easier.

I would like to think :
Pros:

  1. Allows for more flexibility and faster iteration, since services can be developed and deployed independently
  2. Can be easier to scale, since services can be scaled independently as needed
  3. Can be easier to maintain, since changes to one service do not necessarily affect the entire system

Cons:

  1. Can be more complex to develop, since the application is made up of many smaller services
  2. Can be more difficult to understand, since the application is made up of many moving parts
  3. Can be more challenging to deploy, since each service must be deployed separately

The bottom line is, no one approach is the best approach over-all. Each project/company will have different people, needs and resources.

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

I agree that no one solution fits all, but deploying microservices to K8s is super simple. I see your last con as a no-no. For example, before setting CI/CD I created a deployment script that does the deployment for all microservices, and it is the exact same logic every time:

  1. Compile and run tests.
  2. If tests pass, build docker image and upload.
  3. Generate YAML file wth the Deployment and Service definitions.
  4. Apply YAML file.

Micro frontend or microservice, React or .Net: They are all done the same.

Collapse
 
charliesay profile image
Charlie Say

I totally appreciate that :)

I just more mean, in a modern software world when you have 100 microservices that could have been bundled into 1 monolith that you could just deploy once rather than deploy those 100 its easier in that scenario - but again is my point of totally dependent on companies and where they are at :)

Collapse
 
tandrieu profile image
Thibaut Andrieu

Feedbacks I had from teams that start from scratch with a microservice architecture is that they all end up merging services together. After a few month/years, there are too many of them, and they would have preferred starting from a monolith and split it afterward. I had this feedback from several domains: Aeronautics, data processing or advertising.

As a rule of thumb I would say Keep It Simple Stupid.

  • If your logic can fit in a hundred lines, just put a hundred lines in a plain main() function.
  • If it fit in thousand, split into functions.
  • If it fit in tens thousand, split into modules inside a monolith.
  • If it fit in hundreds thousands, split in microservice.

My strategy is to start with a monolith. Then if you identify a part that needs to be updated regularly, independently of the rest, or a part that require high scalability, or part that is clearly identified as a reusable component, split it into its own service.

Collapse
 
alxgrk profile image
Alexander Girke

To throw another phrase into the discussion, I recently learned about Moduliths. If you imagine Monoliths & Microservices as the end of a spectrum, Moduliths claim to be the happy medium. Look at the following for context: github.com/moduliths/moduliths#con...

However, in general I think starting a business with a Monolith (or better Modulith) is by far no bad idea, as long as right from the beginning during everyday work all team members keep in mind that when in comes to the question on how to scale the software and the team, there is almost no other option than getting rid of the Monolith. Call the next evolutionary step Microservices or Independent Systems or whatever.

Collapse
 
jwp profile image
John Peters

Monolithic program architecture is the worst patten for code maintenance ever.

Irregardless of microservices concepts, Monolithic code is massive technical debt from the beginning.

Github has millions of Monolithic Javascript repos. It must have come from Javascript because it is the only discipline that teaches its a good architecture.