TOP architecture solutions: microservices and monolith. How to choose?
In application development, application architecture is used to make the code usable and implementable. Architected solutions are used to ensure this design meets all the requirements of the project area and functional requirements. For the code to fulfill the given conditions of the project, one of the solutions is used: microservices or monoliths. That is, architectural solutions are used to realize technical business needs by converting them into IT solutions, which helps to establish rules and requirements for more accurate implementation and delivery. Equally important will be external factors that can affect the development process.
Monolithic architecture: strengths and weaknesses.
The monoliths are conventionally a single code base. All the bases and the application itself will be on the same level and in the same place. Monolithic applications are more accessible to implement and less complex than microservices. The approximate structure of a monolith can be divided into the user interface, data interface, and business layer, and all this is located in one database. It is worth noting that the number of layers in a monolithic archetype can be numerous, but all these layers will be in a single database.
Strengths of a Monolithic Architecture are:
- Austerity — All the code is in a single solution. You can find holistic code in one place and that helps easily make all changes. It’s impossible to run a single part of the application, you have to run the entire application.
- Easy to deploy — It’s easy to deploy as a single project. It’s only required to deploy a single application for new feature addition or a bug fixing.
- Well-known — Almost all developers have had experience with monoliths in one way or another, which means it’s easier to find a potential developer who can implement a project quickly.
- Easy to debug and test — It’s easy to debug and perform tests in a monolith as all the code is in a single solution. So when you need to debug, it’s only necessary to run the code and debug without doing extra configurations, as well as test performing, you don’t need to configure additional connections between applications. Also, it’s easy to test the UI with some tool like Selenium or to implement end-to-end testing by launching the app.
- Easy to monitor — When a failure/bug occurs, it’s easier to identify where the problem happened because the code is entirely in a single project.
Weaknesses of a Monolithic Architecture:
- Can become too big and complex to maintain — When the project starts, it’s easy to maintain, but through the years, the application can become bigger, and this can be not easy to manage. A monolith application works really well for small or medium applications, but this can become a problem when the application is massive and complex.
- Unavailable time in deploys — When a change or deployment is needed, the entire application becomes inaccessible because of the handling of all the code.
- It can be challenging to work with big teams — It is difficult to onboard new developers when any feature they work on deals with various code pieces scattered all around the codebase.
- Tight coupling — it is pretty tricky to get a specific piece of the application out since all the elements of the architecture are closely linked to each other. Plugging out a specific part of code is painful for the whole monolith.
- Scalability is not flexible — Monoliths can scale, but it’s only possible to scale the entire application. If it receives a lot of requests in only one specific part, you can’t scale just that part, you have to work with the whole app. Also, it’s not always possible to use horizontal scaling; it will be essential to scale vertically, which is generally more expensive.
- Restrict to the chosen technology — It’s challenging to switch the technologies in a monolith application. It means if you’re designing a monolith, expect to use the same technology stack for the long term.
Microservices: strengths and weaknesses
Microservices architecture is an application divided into small services that are independent of each other. They are technology-agnostic, and each has its own database. This architectural solution has many advantages — nevertheless, it has its own challenges and complexity issues. Furthermore, for successful work with microservices, the development team needs to have more experience and seniority.
Some advantages of a Microservice Architecture are:
- Flexible scaling — Microservice is handy in cases where it’s necessary to have high availability of the application. Also, microservices can be scaled independently of the other services. This way, when a part of the application receives many requests, it’s possible to scale only the specific microservice instead of scaling the whole application.
- Deploy independently — It’s possible to deploy only one microservice, as they are loosely coupled (independent of each other). This way, require the whole application to stop working, for a few moments because only a tiny part of the app will be updated/changed.
- Eliminate the single point of failure — Splitting the application across many small services eliminates the “single point of failure” in the app.
- Reduces the risk of breaking the app — If a microservice fails, it will not affect the rest of the application; it will only affect that single microservice while the other parts of the app will continue working correctly.
- Minimize downtime when a new version is released — The application will not stop working for a while when a new version of the microservice is released; only the part which uses that specific microservice will be unavailable.
- Can be easier updated — Since a microservice is not, in general, a big application, it’s easier to change something in the code or even update the framework which is used by the microservice.
- Easier to work with different teams — When working with many teams, each team can be responsible for a specific microservice or a group of microservices, separating the responsibility of each part of the project between the teams.
- Easier to understand — A small application is in most of the time, more straightforward to understand than a bigger application.
- Easier to expand — It’s easy to expand an application by creating new microservices.
- Independently changeable — When the microservice itself needs to change, this will not affect the other microservices.
- Can have different databases — It’s possible to choose a separate database for each microservice. A relational database can be the best option in one microservice, and for other microservice, a NoSQL database fits better, which is possible to achieve when working with a microservice. Which database is defined only by the developers.
- Technology agnostic — Each team can define which technology they want to use in each microservice. So microservice can have different technology; one can be done in .NET, or in Java, another in Node, o in Go, and so on.
- Agility — With microservices, it’s effortless to add something new and deploy a new version without impacting the whole app.
Disadvantages of Microservice Architecture
It’s much more complex to work in a microservice architecture than working in a monolith application. Of course, a microservices architecture brings a lot of benefits but also comes with many challenges. There aren’t ideal microservice architectures:
- There is an orchestration with the single point of failure problem as API gateway, so therefore necessary much emphasis to this part.
- And there is choreography with the single point of failure as a broker which gets all attention.
- It doesn’t matter wich type of microservices you chose, but it’s necessary to have a team of developers who knows how the system should work; or an excellent team leader who will take care of architecture;
- Many technologies and languages, or many people and areas of expertise — more difficult project rotation.
Choosing application architecture: Corewide way
We recommend specific architecture to our clients based on criteria we’ve defined through our experience
- We suggest monolithic architecture when the application is already with a clearly delineated little scope or MVP/prototype that you intend to rewrite anyway
- When the application is self-sufficient and scales well horizontally and vertically, we chose the monolith
- When an application combines heterogeneous functionality, it is better to go straight to microservices. Moreover, if the app has the back-end more than in two languages or the app has the big data / API — we also choose the microservices, as applications like this are benefited from atomic components that each do their bit of work
- If an application needs flexible horizontal scaling — pick microservices as you can scale a separate service. When flexibility is in question, microservices are often the answer.
- It’s important not to confuse microservices with sidecar services. A multifunctional application with a dozen identical workloads running in parallel performing various tasks is still a monolith — but the kind that cleverly exploits its architecture.
- An application designed as a monolith often becomes the first microservice — when you decide to separate the new functionality from the existing app codebase instead of including it there. Moreover, monoliths are usually easier to rewrite for microservices from scratch than to remove separate blocks and turn them into services
- If you are aiming at microservices, you should immediately decide on two things: data handling scheme (orchestration vs. choreography)
- what functional scope limit — to avoid creating a new service unless its functionality is out of the scope of the existing one.
It’s good to take into account the points that were explained to choose the right architecture for your project, as each kind of architecture brings some advantages and some disadvantages. As they say, “there is no silver bullet”, so each approach will bring pros and cons.
To decide which architecture you should use in your project, always try to identify some points making some questions as:
- Is going to be big and complex?
- Do my team, or I have good knowledge about the domain?
- Does the app need flexible scaling and high availability?
- Does my team have experience working with microservices?
It’s also essential to consider the knowledge of the team and the complexity of the system. Microservice architecture can be a good option for your project if you answered yes to most of these questions. But if you know that the application will not be so big, or the domain rules are not well-defined, or you’re building just a simple application, or you don’t really need the app to have 99.9% uptime or the application is not going to be too big or too complex, a monolith app can be the best option for you.
Monoliths are simpler and easier to implement. Still, the project can be a bit difficult to maintain when the application grows too much and more developers are working on the project. A microservices architecture brings much more complexity to the project, but it also allows you to have smaller and separated applications, allowing you to use different technologies in each microservice, allowing flexible scalability and making it easier to work with different teams. Being aware of all these points can help you define which architecture will fit better your application.