Photo by Timelab Pro on Unsplash

Monolith vs Microservices

Icebob
Moleculer
Published in
7 min readOct 25, 2022

--

Introduction

If you’re a developer, there’s no doubt that one of the most important questions you have to answer is “should my project be a monolith or microservice?”. Choosing an appropriate architecture is really hard, especially considering the fact that this decision may affect the entire life-cycle of the project. Additionally, making the right decision is often difficult as business requirements may change during the actual development. But what if you don’t have to make this decision at all? What if you can seamlessly switch between the monolith and microservices? In this article you will see how to build your project and enjoy the benefits of both architectures.

The illustration is created by N-iX

Monolith

A monolithic architecture is a traditional model of a software program, which is built as a unified and self-contained unit that encompass the entire business logic in a single code base. The main limitation of monolithic approach is that it usually doesn’t age well. As your team and the code base grows it becomes increasingly challenging for everyone to be productive. The time that the team spends solving code conflicts of different PRs will start to grow. Whenever this moment happens, it’s probably a good time to consider abandoning the monolith approach. Nevertheless, monolith has several advantages.

Advantages of a monolithic architecture

  • Simplified deployment — Deployment from a single directory is much easier than having to worry about a bunch of repositories, different programming languages, runtime engines, etc.
  • Development —Single code base speeds up the development.
  • Performance — Communication is in-process, so there’s no network overhead.
  • Simplified testing — Testing, especially end-to-end, can be performed faster than with a distributed application.
  • Easy debugging — Single code base makes it easy to track the code execution flow and finding bugs.

Disadvantages of a monolithic architecture

  • Slower development speed — A large monolithic application makes development more complex and slower.
  • Scalability — It’s impossible to scale some specific component of the application.
  • Reliability — An error in a single component of the monolith could affect the availability of the entire application.
  • Lack of flexibility — A monolith is constrained by the technologies that are already in use. You can’t use new language or a framework to create a new component. This would require migrating the entire code base.
  • Deployment — Making even a tiny change (e.g. bug fix) to a monolith implies re-building and re-deploying the entire application.

Microservices

Microservices architecture is an approach for building applications that rely on a series of independently deployable services. These services have their own business logic and database with a specific goal. Updating, testing, deploying, and scaling is granular and can occur within a specific service. Microservices decouple major business concerns into separate and independent code bases.

Advantages of microservices architecture

  • Flexible scaling — If a microservice reaches its load capacity, new replicas of that service can be rapidly deployed to help relieve pressure.
  • Continuous deployment — Adding new features and making incremental releases is easy, fast and has less costs.
  • Highly maintainable and testable — It is easy to isolate the problems and perform bug fixing in individual services. Writing unit tests is a no-brainer.
  • Deployment — Since microservices are individual units they allow to easily deploy new features, without interfering with the rest of the infrastructure. The threat of bringing down the entire application is very low.
  • Technology flexibility — Microservice architecture gives the development teams the freedom to select the tools they desire.
  • Less code conflicts — Being small and independent business components means that teams are more autonomous and own the their code. Chances of having conflicting PRs are low, making the teams more productive.

Disadvantages of microservices architecture

  • Development complexity— Managing, coordinating, and developing microservices in a way that they seamlessly execute business requirements is difficult. If not done properly, it may result in slower development time and poor performance.
  • Exponential infrastructure costs — Each new microservice may require a unique deployment pipeline, hosting infrastructure, monitoring tools, and etc. All of this involves additional costs.
  • Debugging challenges — A single business process can run across multiple microservices scattered different machines — making it harder to pinpoint the errors.
  • Ownership of services — Over time, dev teams are dissolved, merged, reassigned, etc. — making it hard to define a clear ownership of the services and providing support for them.

Who is the best and which one should I choose?

You don’t have to choose any of them. Why? With Moleculer framework you can develop your project as a monolith and then easily switch to microservices without modifying your services. How? Just install a message broker (NATS, Redis, etc) as a transporter and deploy the services individually. All other things will be done by Moleculer.

What about the…

  • …service discovery? It’s covered by Moleculer.
  • …service registry? It’s covered by Moleculer.
  • …observability? Moleculer has a built-in logger, metrics and tracing module with many exporters (Prometheus, Jaeger, Datadog, etc).
  • …fault tolerance? Moleculer has several fault-tolerance features like retries, timeout, fallback, bulkhead, etc.

Create a Moleculer project

To create a Moleculer project, you should install the Moleculer CLI. It helps you to create a project based on the official template.

Install Moleculer CLI:

npm i -g moleculer-cli

Generate project

moleculer init project medium-demo

Press “Enter” on all questions to use the default options.

Now your monolith & microservices project is ready to use. 🎉

Running as monolith

At development, you can start the project as a monolith. In this case, all services are started on a single node and can communicate with each other directly. This deployment allows to easily debug and test the project.

cd medium-demo
npm run dev

You can use this mode in production at the beginning to keep low the deployment costs. When your project starts to grow and the number of customers increases, you can switch to microservices anytime without changing the service codebase.

Open the http://localhost:3000/ link in your browser. On the Welcome page, you can call the services via the API gateway.

Welcome page

Running as microservices

The project contains a Docker Compose file, it starts the project as microservices architecture. It contains the following services:

  • API gateway service to expose the Moleculer services via REST API via http://localhost:3000/api
  • “greeter” sample service
  • “products” sample service
  • MongoDB for “product” service
  • NATS server for transporter
  • Traefik reverse proxy to support multiple API gateway instances.

Start the services separately

docker-compose up -d

If you list the running containers you should see the same:

docker-compose ps

How does it work?

If you look under the hood (i.e., docker-compose.yml file), you will see that you can instruct the services that should run inside of each container via “SERVICES” environment variable. During the boot, Moleculer will process this variable and it will only start the services that are declared there. This approach allows you to easily re-configure your application and deploy, if necessary, several services in a single container. Doing this will cut down the network latency between the services. The additional benefit of this approach is that Docker builds only one image and, thus, saves disk space.

Scaling

To scale up the services, just execute the following command:

docker-compose up -d --scale api=3 --scale greeter=3 --scale products=3

It will start 3 instances of each service.

If you open http://localhost:3000 in your browser, you will see that every service is running on 3 different nodes:

The generated project contains a sample Kubernetes yaml file to help you with the deployment on a Kubernetes cluster.

Conclusion

There are plenty of articles and books explaining how to pick between monolith and microservices. However, you don’t have to choose either. Choose Moleculer framework. You will get the speed and efficiency of a monolith with the flexibility of a microservice architecture. Moleculer’s ability to switch between a monolith and a microservice deployment allows you to take advantage of both architectures.

If you want to learn more about Moleculer then check out our website https://moleculer.services or GitHub.

Follow us on Twitter at @MoleculerJS or join Discord chat.

--

--

Icebob
Moleculer

A full-stack javascript developer, founder of Moleculer