Microservices are a collection of small services that, when combined together, make up an entire application. That you know.
However, beyond this point, it’s hard to define a microservice more specifically, because microservices vary widely in form.
This begs the questions: How should you size and structure your microservices in order to build the most effective application? How does the nature of your organization affect the types of microservices you create? What can you do to ensure that microservices prove as agile in practice as they are in theory?
Let’s explore these questions by taking a close look at what to consider when designing microservices.
Pizzas and Teams
There are many ways to look at microservice size. One common approach is to have pizza-sized teams with about five people managing a single service. According to Conway’s Law, an organization’s structure will model its communication patterns closely on itself. This is a natural outcome rather than a planned one, and is worth keeping in mind when planning your microservice design. However, you should be careful to not put the focus entirely on available talent and ignore those opportunities where you can think beyond your existing team to the ideal team structure.
Microservices enable this kind of thinking and flexibility—in fact, they call for it. Microservices make it easier to build fluid teams that share responsibilities for developing and managing the same sets of microservices. This organizational structure is more agile than a siloed approach in which each team is responsible for one component of the application, and there is no shared effort or collaboration.
Boundaries and Contexts
Martin Fowler discusses bounded contexts, where microservices are defined by clearly defined boundaries. For example, all tasks related to closing a deal can fall within the sales context, and all tasks related to handling customer queries can fall into the customer support context. These contexts can be translated into a microservice. This approach is formally called Domain-Driven Design (DDD). It focuses on clearly defining boundaries between each service, and explicitly stating their interrelationships.
Keeping Microservices Small with Containers
Perhaps the biggest contributor to microservice size is the space-saving that containers have introduced. With hypervisor-based VMs, each instance of a VM needs to run a full-blown OS inside a virtual server. This takes up many GBs in space and is not feasible for a microservices system. On the other hand, containers which share a common guest OS for as many as a thousand containers are just tens of MBs in size. Containers bring much-needed speed at every step of the microservices lifecycle—Whether creating instances, restarting failed ones, or destroying unused instances, they’re all lighter and faster with containers.
Another aspect of microservices is that they keep services small by developing new functionality and features not as new components within the system, but by offloading functionality to the API. This way both internal services and external apps interact with a microservice via the API, thus bringing added functionality and consistency across the system, all while keeping services lightweight.
Then, there’s the overhead for managing microservices. Each microservice needs its own development pipeline complete with versioning, automated builds and tests, and deployment cycle. It’s important to ensure that microservices aren’t too small. If this happens, the cost of managing and maintaining the service is greater than its actual use (known as the nanoservice problem).
Size is a Key Factor of a Holistic Microservices Strategy
There have been approaches similar to microservices, based on dividing the application into smaller parts (most notably the Service-Oriented Architecture (SOA) movement that preceded microservices). However, what separates microservices from forerunners is the focus on the user experience, and putting the needs of the modern application first, then deciding which infrastructure and tooling to employ to meet those needs.
The state of your organization plays a key role in deciding how granular your microservices should be. The more distributed your system is, the more likely it is to slow down development. It helps to find the right balance between how consolidated and granular your microservices are. As you begin your transition to microservices, taking it slow and decomposing one service at a time is realistic, rather than expecting to have a fully functional microservices system in just weeks.
While the size of the microservices in your system matters, the approach toward decomposing an application, implementing a service mesh, distributed monitoring, automation, and independent development cycles is what defines microservices. If you focus on getting these foundational principles of microservices right you’ll find that your microservices are automatically right-sized—not too big, not too small. The important goal is to ship applications faster, and ensure what you ship is reliable. When done right, this is the promise and benefit of microservices, and the size of each microservice merely serves this larger goal.