Building a quality product doesn't mean you can't start with a monolith and expand to microservices.
We're quite fond of buzzwords in the tech world. Cloud, Big Data, and Blockchain are undoubtedly terms you've heard for the umpteenth time this week. You may have heard of Microservices and how they can help you defeat the dreaded Monolith application. You may have even listened to a keynote speech by a large software company, discussing how they tamed their monolithic beast and transitioned to a microservice architecture, ushering in a development renaissance of sunshine, rainbows, and unicorns.
As of late, our clients have increasingly been asking us about microservices and if they're a good fit for their projects. While this shift in architecture might make sense for a Fortune 500 company, does this wisdom hold true for a startup or small business? Are microservices really the future of software development? Do monolithic applications still have a place in our development toolbox? Before we can understand the nuances in choosing microservices over monoliths, we need to know what these design paradigms entail.
A monolithic application, sometimes referred to as a monolith, is a type of software architecture in which all components of the application are packaged together as a single unit and/or deployable module. This means all functionality of the application exists in the same code base, is deployed together at the same time, and runs together on the same server(s).
A monolith has several benefits, especially for new products and platforms:
- Simple to develop: everything uses the same language and framework, and is all a single application.
- Easier to adapt to new requirements: adding new features or drastically changing existing ones is much easier when everything is part of the same code base.
- Straight-forward to deploy and scale: there's only one application to release, and capacity can be increased by simply adding more instances behind a load-balancer.
By contrast, a microservice architecture is one in which the functionality of the application is separated into distinct components called services. Each service is generally its own application, with its own code base, programming language, framework, and database. Each service is developed, tested, and deployed independently of other services. Services communicate with one another using well-defined APIs to implement the totality of the business functionality.
A microservice architecture has several advantages over a monolith, especially for large, complex, well-established applications:
- Maintainability: each service is relatively small, which makes maintenance easier.
- Scalability: services can be scaled independently, based on the service's operating requirements.
- Development velocity: Teams can autonomously develop and deploy their own services.
While microservices have many benefits for established projects with large development teams, monoliths are generally preferred for starting greenfield projects. Monoliths have the benefit of being quicker and less expensive to build, launch, and refine. Since a monolith is comprised of only a single code base, features and ideas can be rapidly implemented and deployed. This is especially important in the project's infancy when business requirements and use cases are still largely unknown and require constant market validation.
When to Transition
If starting with a monolithic architecture is generally the right idea for new projects, how do we know when to start transitioning to microservices? While some believe the impetuous to switch to a microservice based architecture is driven by scaling or performance concerns, it is, in fact, most frequently prompted by a growing development team. As a project expands and requires more developers, there is a natural desire to split developers into separate teams, with each typically focused on a single component of the application. While we want to treat teams working on a monolithic application as independent, in practice they rarely are.
As all teams share the monolith's code base, even small changes can require immense communication and collaboration between teams. Thorough QA testing becomes required for each release, as changes by one team may conflict with changes from another. The release cycle slows down, sometimes to one-month (or even longer) between deployments. Developer productivity dwindles as each change requires inter-team review and coordination to avoid stepping on each other's toes.
Making the shift to microservices helps bring the application's architecture in line with the development team's structure. Each service can be owned and maintained by a small development team. Continuous Integration (CI) and Continuous Delivery (CD) pipelines can be more easily implemented in a microservice architecture, allowing changes to be released immediately. (In fact, some very large companies may deploy 10,000 times per day, with zero downtime.)
While microservices aren't all hype, they aren't a silver bullet either. They're simply another tool in the developer's toolbox. As with any tool, its use must be considered on a case-by-case basis. In a future post, we'll discuss common strategies for transitioning a monolith to microservices.