Microservices vs Monolith

2023-09-28

When starting a new project, one of the architectural decisions is whether to build it as a monolith or as microservices. I have worked with both approaches and each has trade-offs worth understanding before making a choice.

Monolith

A monolith is a single application where all the code lives together. The user interface, business logic, and data access are all part of one codebase and deployed as a single unit. Most projects start as a monolith, and there is nothing wrong with that.

The advantages of a monolith are simplicity. There is one codebase to work with, one build process, one deployment, and one database. Debugging is straightforward because everything runs in the same process. If something goes wrong, we can trace the issue through the code without jumping between different services.

The downside shows up as the project and the team grow. When many developers work on the same codebase, merge conflicts become more frequent. A small change in one module might accidentally break another module. Deploying the entire application just to fix a small bug in one area is also not ideal. And scaling is all or nothing. If one part of the application needs more resources, we have to scale the entire application.

Microservices

Microservices break the application into smaller, independent services. Each service handles a specific part of the business. For example, an e-commerce application might have separate services for user accounts, product catalogue, orders, and payments. Each service has its own codebase, its own database, and is deployed independently.

The advantages are flexibility. Each team can work on their service without affecting others. Services can be deployed independently, so a bug fix in the payment service does not require redeploying the product service. Each service can be scaled based on its own load. The payment service might need more instances during a sale event while the product service stays the same.

The downsides are complexity. Instead of one application, we now have many. They need to communicate with each other over the network, usually through HTTP or message queues. This introduces latency and the possibility of network failures. Debugging becomes harder because a single user action might involve multiple services. We need infrastructure for service discovery, load balancing, logging across services, and distributed tracing.

Which One to Choose

From what I have seen, most projects should start as a monolith. The overhead of microservices is not worth it for a small team or an early-stage product where requirements change frequently. It is easier to refactor code within a monolith than to reorganise service boundaries.

Microservices make more sense when the application has grown large enough that different parts have clearly different scaling needs, or when the team has grown large enough that independent deployment becomes valuable. The transition from monolith to microservices can be done gradually by extracting one service at a time from the monolith, starting with the part that benefits the most from being independent.