In the software development life cycle, you have two major points in time when you’ll think about architecture the most.
The first one is when you start to build a new application and you have a beautiful greenfield in front of you. Architects and developers love it because they have a lot of freedom and can design everything according to their vision.
The second point in time is more challenging, and occurs when the application starts to have issues with further development, its size, complexity, or scalability. The decision that you need to make will be, at first sight, quite straightforward because you have only two options: monolith or microservices. But is there a third option? Let’s look at it more closely.
What is a monolith?
When you hear the term monolith, you probably think of a single massive stone or rock. The intuition is also true when it comes to software development. Monolith means a single large codebase representing the whole application.
All functionalities are tangled together in a single deployable package. Depending on the size and complexity, it is good practice to divide the monolith into multiple modules which are tightly coupled together. The diagram below represents the idea behind the monolithic architecture.
Pros of monolithic architecture
- Simpler to develop, especially for small applications. A single developer or a team focuses on a single centralized solution resulting in a faster time to market.
- Easier to test as there is only one code repository to keep track of when testing and debugging.
- Easier to deploy and run the application as it consists of only one jar/war file.
- Requires less specialized skills in terms of development, deployment, and maintenance.
- Simple security management as the security is handled in one place, rather than having to track vulnerabilities across all microservices.
- No additional communication overhead between multiple teams and no coordination needed.
Cons of monolithic architecture
- The application can become complex and hard to maintain over time. A large codebase is difficult to manage as all changes and upgrades need to be applied to the whole application at once.
- Difficult to scale. Scaling a monolith in the majority of scenarios means vertical scaling. Horizontal scaling, adding additional application instances, requires infrastructure changes like an introduction of load balancers, and in some cases, application redesign is needed.
- Technology limitations. Due to a single technology stack, there is no possibility of using multiple programming languages to support a specific application feature need.
- Single point of failure. Any issue like performance issues or a memory leak will impact the entire application.
- Harder to involve multiple teams to develop the application in parallel.
What is microservices architecture?
Some of you still remember the Service-Oriented Architecture (SOA) concept that emerged 15-20 years ago. SOA promoted centralized, oriented architecture that focuses on services. It aimed to decouple large monoliths and put pressure on service reusability.
Microservices architecture is the next evolutionary step of SOA. Application functionality is broken down into a number of smaller services interconnected with each other by lightweight protocols like REST or gRPC.
Often, when developing a microservice, a team has the freedom to choose technologies that suit them the best, including programming languages and database.
Pros of microservices architecture
- Easy to develop and maintain a single microservice because it encapsulates a specific business capability developed by only one team. The development team can focus on specific functionality without a need to know the whole application.
- Quick and continuous deployments of a microservice can happen independently from other parts of the application.
- Scalability and reliability are provided by design. The current technologies like Kubernetes or serverless provide seamless scaling capabilities and failover options.
- Each microservice can use different technology based on the business requirement or team skills.
Cons of microservices architecture
- The microservice ecosystem is harder to manage. It requires additional common governance rules and oversight. Microservices need a contract to communicate with each other.
- A distributed system is more complex to test, track bugs, and monitor.
- Skilled developers are needed to work with microservices. Some functionalities like exception handling and eventual data consistency are harder to implement.
- Deployments might be challenging, especially when dependent changes are introduced to a number of microservices at the same time.
- Security must be the design principle and needs to be implemented at the very beginning.
- Data located in multiple locations makes reporting and data analysis more difficult.
- Fallacies of distributed computing are often ignored.
Is there an alternative?
In real life, in the majority of cases, you’ll see a combination of both monolithic and microservice approaches. The hybrid approach is the most flexible and most pragmatic approach in many cases. Software architecture needs to accommodate multiple constraints like time, budget, business priorities, organization maturity, or multiple COTS and SaaS solutions.
How to succeed in developing monolithic and microservices architectures?
- Monolithic applications might serve well for startups but cause problems for large-scale enterprises.
- Multiple complex functionalities are a good indicator for a modular microservices approach.
- Try not to overengineer by focusing on business needs and value delivered by the application.
- Agree on a functional strategy that will determine the product life cycle and design an architecture that supports desired business outcomes.
- Bear in mind the business and technical challenges and non-functional requirements, e.g., the number of users and scalability needs.
- Be agile and adjust. Starting with a monolith and introducing microservices at a later stage is not a bad idea after all.