Considering Size and Scope of Services
There is an undeniable push in tech to build microservices—and for good reason. Smaller components pair well with modern delivery practices and objectives. According to Gartner, two out of three business leaders believe that they must pick up the pace of digitalization to remain competitive. In turn, businesses are working to pick up the pace of software delivery. And creating smaller components with smaller change sets and a smaller blast radius is a good way to do that because the components are easier to test, secure, deploy with confidence, and scale independently of other components. Pair smaller components with DevOps practices and we end up with forty-six times more frequent deployments with five times lower failure rate, according to Puppet Labs. While these benefits are appealing, the reality is that building microservices comes with complexity and new challenges. And while using microservices is the latest trend, we shouldn’t ignore the benefits of monoliths: easy to make changes, add functionality, understand, and operate. I’m not suggesting we continue building monoliths. Rather, we should be intentional about the path we choose and the approach we take.
Over several years, we went from “services” and “service-oriented architecture” to “microservices.” This shift in terminology would imply that size matters when building services, and I believe that’s generally true. But how small is micro? Finding the right size for your service is an art, not a science, and should be a result of your priorities. We want to focus on our customers first and foremost, and in order to keep our customers, we need to increase business agility and innovation. In order to do that, we need to be able to deliver value more frequently and be able to adapt to customer feedback and evolving needs. To best respond to feedback, we need people (teams) to own the products their customers (both internal and external) use to become intimately familiar with the customer problem. We can then empower and incentivize the team to solve the problem and invent on behalf of their customer.
In order to own a product or service, we typically organize as small teams, typically five to ten people, that are each in charge of a single component of a product or service. The components must be small enough for the team to fully own, from ideation through operations. If the components are simple enough that a single two-pizza team can own several components, then so be it. But as complexity grows, we should intentionally simplify these components, shrinking them in size (or splitting them into multiple components) to ensure each component can be fully owned by a single team.
What’s in a name?
Regardless of your definition of a monolith, I think we can agree that what we’re moving away from is a tightly coupled application that attempts to do too many things and inhibits speed. Call it “microservices,” “macroservices,” or just “services,” it really shouldn’t matter. The twelve-factor app methodology provides a good starting point for the structure, configuration, and separation of duties of a modern application. By focusing on dependency management, configuration by the environment, deployment, etc., applications become easier to operate and change. In my opinion, if you build twelve-factor apps first and worry about the granularity of your component second, you can avoid a common anti-pattern: premature optimization.
Learning as You Go
As we work to build environments that enable fast experimentation and learning, we need to build and release software quickly. Serverless is helping companies do that by allowing them to focus solely on the business logic and leverage building blocks from cloud providers to easily build solutions. But sometimes the problem is complex. Early on, we often lack a full understanding or appreciation for user needs, the data lifecycle, the scaling profile, or usage patterns of the component we’re building. You should consider each component as being on a journey; there is no end to a component’s improvement until it is retired. We have to learn and improve along the way. While all the talk about serverless and microservices might compel you to make things as small as possible from the beginning, I find it to be much easier to start with a coarse-grained approach and focus on optimizing and simplifying over time. Organize your teams around ownership and commit them to owning and improving their components over time to better deliver customer value. A perfected granular set of services that cover every possible use case takes time to build and may seem like a smart foundation, but how do you know you’re going to need it? Instead we should iterate, shrink, and refactor over time to build the components we actually need when we have good reason to build them.
Make constant, small iterations and stop worrying about size. Commit to ownership and improvement and just build services.
On-Demand Webinar: Modern Applications on AWS
Modernizing How You Build, Part 1—The Modern Application
Modernizing How You Build, Part 2—Taking the First Step
Read more of my blog posts