Service Decomposition

Basic System Design
≈ 2 min read

Split by Responsibility

Decomposition answers the question: which parts of the system can actually live relatively independently? A useful boundary usually surrounds a complete business capability—such as order management or payment processing— rather than a technical layer such as “controllers” or “repositories.”

Bad split:
UI Service -> Logic Service -> Database Service

Better split:
Orders Service | Payments Service | Users Service

In the second version, each service keeps its API, business rules, and data access together. Changes to one capability are less likely to require simultaneous changes in every other service.

Look for Things That Change Together

A good candidate for a separate service combines rules and data that often participate in one task. If two parts make almost every change together, require one shared transaction, and constantly request one another’s internal data, they were probably split too early or along the wrong line.

It is useful to look at business scenarios, team responsibility, and load characteristics. Different reasons can point to the same boundary, but no formal class or table size defines it automatically.

Start with Larger Parts

A coarse boundary can be split again later more easily than dozens of excessively small services can be maintained continuously. At an early stage, it is more important to reduce inter-service dependencies and keep a cohesive model inside each service.

The number of services is not a quality metric. The goal of decomposition is independence of change, not the maximum number of processes.