Welcome back to our series about apps architecture. In the previous article, we introduced both monolithic and microservice architectures, how functional needs and available resources shape the structure of an application. However, each architecture includes a set of trade-offs that must be carefully considered before settling on the application's ultimate structure.
Development complexity, scalability, time to deploy, flexibility, operating cost, and dependability are all factors to consider. Let's take a closer look at each trade-off.
Development Complexity
The work required to install and administer an application is referred to as development complexity.
Monolith - one programming language; one repository; enables sequential development.
Microservices - multiple programming languages; multiple repositories; enables concurrent development (in that meaning that the coding process is independent or decoupled entirely from the broader microservice ecosystem outside of simple hooks or endpoints, individual interactions are far more straightforward).
There are some notions about development complexity in microservices - they complicate networking, make it pay more attention to transactions and data consistency. When using microservices, you must determine how each service interacts with the others on a macro level. While the creation of individual units is considerably simpler, the entire system becomes increasingly complicated.
Because everything is inextricably linked, a monolith may be updated as a whole. In a microservice design, updates throughout the whole system (such as adopting a new version of a selected language or protocol) might be more expensive since it is dispersed. You're upgrading both the microservice and the components that make it all work together. At an enterprise size, resolving these challenges will very certainly need the use of a management layer. Containerization and service mesh, for example, make it possible to have dispersed environments while yet having a unified control plane.
Scalability
The ability of an application to scale up and down in response to incoming traffic is referred to as scalability.
Monolith - replication of the entire stack; hence it's heavy on resource consumption.
Microservices - replication of a single unit, providing on-demand consumption of resources.
Time to Deploy
The construct of a delivery pipeline that is utilized to ship features is referred to as time to deploy.
Monolith - one delivery pipeline that deploys the entire stack; more risk with each deployment leading to a lower velocity rate.
Microservices - multiple delivery pipelines that deploy separate units; less risk with each deployment leading to a higher feature development rate
Flexibility
The capacity to adapt to new technologies and provide new functions is referred to as flexibility.
Monolith - low rate, since the entire application stack might need restructuring to incorporate new functionalities.
Microservices - high rate, since changing an independent unit is straightforward.
Yet, the flexibility really depends if the microservices are split right - that is actually one of the greatest challenges. In other words, well structured single-repo monolith could be more flexible than wrongly designed microservices.
Operational Cost
The cost of essential resources to release a product is referred to as operational cost.
Monolith - low initial cost, since one code base and one pipeline should be managed. However, the cost increases exponentially when the application needs to operate at scale.
Microservices - high initial cost, since multiple repositories and pipelines require management. However, at scale, the cost remains proportional to the consumed resources of affected microservices at that point in time.
Reliability
Reliability refers to how an application recovers from failure and the tools used to monitor it.
Monolith - in a failure scenario, the entire stack needs to be recovered. Also, the visibility into each functionality is low, since all the logs and metrics are aggregated together.
Microservices - in a failure scenario, only the failed unit needs to be recovered. Also, there is high visibility into the logs and metrics for each unit.
In both cases, you usually want to aggregate all the logs in one place with options to filter out wanted components, such an approach allows you to see both the high-level and detailed perspectives. In the case of the monoliths, logs are collected in a scope of a single unit and the log collection process is a more sequential one. But in the case of microservices, each service has its own log processing flow and can be analyzed as a decoupled one without additional filtering.
Summary
Each application architecture has a set of trade-offs that must be taken into account at the start of a project. But it's even more vital to know how the program will be maintained in the future - at scale, under stress, and sustaining several releases per day, among other things. There is no one way to product design, but a thorough knowledge of the trade-offs will help you plan your project.
Regardless of whether a monolith or microservice architecture is chosen, the route to cloud-native deployment is guaranteed if the project is linked with a fast delivery pipeline, the flexibility to embrace new technologies, and the ability to easily add functionality.
Reach out to get more information.
Artyom, sr. software engineer
References: