In the world of cloud-native applications, one big question that keeps coming up is this: How should I divide my application into services?
The question is a basic one. Should I take this module and put it all in one service, or is it best served by being split into multiple services? Certainly, there are many points of view here; some advocate for fewer larger services, some advocate for more smaller services.
Smaller or Larger Services?
If you build your application so the services are very small, then the individual services themselves are much easier to comprehend and therefore support. Additionally, individual services can be scaled independently in a microservice architecture, and you can highly tune your cloud resources consumed. Smaller services are also more appropriate for a serverless environment, such as AWS Lambda.
Yet smaller services have a major disadvantage. The smaller you make your services, the more complex the system for interconnecting those services becomes and the more dependent your application becomes on managing service dependencies and understanding the complex interservice interactions that are needed.
This problem is reduced when you instead build larger services. The larger your services, the fewer total services you need to support and the simpler your service management infrastructure becomes. The downside of larger services, of course, is that the services themselves become more complex and hence harder to support. Additionally, the larger your services, the harder it is to fine-tune your cloud resource usage and hence manage your infrastructure costs.
What Makes a Service the Right Size?
So, what’s the right size for a service? There is no one answer to this question, but I have a process, which I call The Goldilocks Calculation, for determining the right size for your services in a cloud-native application. The idea is to find the appropriate size for each service in your application—not too big or too small—to optimize your cloud-native application experience.
The process is based on both the needs of the application and the needs of your organization supporting the application. The right size of services for your application depends on these three critical characteristics.
Characteristic One: Your Service Infrastructure
How mature is your service infrastructure? Your services run on an infrastructure that your organization must provide. Generally speaking, the more mature the service infrastructure, the greater the number of services your system can maintain before becoming overwhelmed with complexity.
How do you determine how mature your infrastructure is? Your infrastructure maturity depends on infrastructure components such as deployment pipelines and service management tooling, along with shared infrastructure components such as inter-service communications channels, pipelines, and mechanisms. The better the defined processes for building and maintaining the infrastructure, the greater the maturity of your overall infrastructure.
A more mature service infrastructure that can handle a larger number of services means you can safely divide your application into a greater number of smaller services without suffering significantly increased infrastructure complexity.
Characteristic Two: Abilities of Your Development Teams
The maturity of your individual development teams is critical to determining the appropriate service sizes for your application.
The greater your individual development team’s maturity, the larger and more complex a service they can effectively understand and support. The lower the development teams’ maturity, the smaller and simpler you need your services to be to provide the same level of supportability.
A more mature development organization means larger services can be effectively utilized, reducing the overall number of services and hence decreasing your overall system complexity.
Characteristic Three: Abilities of Your Architecture Team
How mature is your business with respect to application architecture? Is application architecture a core value for your company that is appropriately staffed with experienced software architects? Or is your software architecture haphazard and spun together by developers only as needed during the development process?
The more mature your application architecture discipline is, the larger and more complex your service infrastructure can be. This is because a more mature architecture team will be able to make appropriate infrastructure architecture decisions that improve the overall system effectively.
Without a solid architecture discipline in your application development process, new services are added haphazardly and without thought. The result is a spaghetti-like infrastructure that becomes quickly untenable.
The greater the maturity of your overall application architecture team, the greater the inter-service complexity that can be managed and maintained (and hence the larger number of smaller services that can be tolerated).
Driving for the Right Service Size
Determining where to put service boundaries is an important and continuous architectural decision that is critical for all cloud-native applications. Being thoughtful and building services that are not too big, nor too small, but just right in size is critical to maintaining the balance between service complexity and infrastructure complexity that is appropriate for your application, your development teams, and your overall business needs.