Coupling and Cohesion
Keep things that change together close together, and things that change independently apart.
To an executive
When parts of a system are tangled together, a small change needs many teams to move at once. Looser coupling means faster delivery and fewer coordinated releases.
To an engineer
Group what changes together and separate what changes independently. Check for hidden coupling through shared schemas, synchronous call chains, shared release trains and shared assumptions about meaning.
The idea
Larry Constantine developed the ideas in the 1960s, and they reached a wide audience in the 1974 IBM Systems Journal paper "Structured Design" with Wayne Stevens and Glenford Myers. Two measures sit at its heart:
- Cohesion: how strongly the parts inside a module belong together.
- Coupling: how much one module depends on another.
Aim for high cohesion and low coupling. Nearly every structural principle since, from information hiding to microservices, restates this in some form.
Coupling comes in many forms. Data coupling through a shared schema, temporal coupling through synchronous call chains, deployment coupling through shared release trains, and semantic coupling when two parts must agree on what a value means. A system can deploy independently yet still be tightly coupled through any of these.
Why it works
Change is local when related things are together. If the parts that change for one reason live in one module, a change touches one module.
Low coupling limits the ripple. Fewer and narrower connections mean fewer places a change can break something else.
Cohesive modules are easier to understand. A module with one purpose can be read, tested and owned on its own.
Where it applies
- Service decomposition, where boundaries should follow rates and reasons of change, not technical layers.
- Code structure within a service, at the level of packages and classes.
- Team design, where teams that must coordinate on every change are coupled too.
- Migration planning, where the coupling in the old system decides what can move separately.
How to apply
- Look at change history. Files and services that always change in the same commit or release are coupled, whatever the diagram says.
- Name the coupling. For each dependency, say which kind it is: data, temporal, deployment or semantic.
- Regroup by reason for change. Move parts that change together into one module, and split modules that change for unrelated reasons.
- Make the remaining coupling explicit. Put it behind a narrow, versioned interface, and prefer asynchronous links where timing does not matter.
Example scenario
Pricing, promotions and tax were split into three services by technical layer. Every pricing change needed coordinated releases of all three, and a shared database schema meant one team's migration could break the other two. On paper they were microservices; in practice they were a distributed monolith.
The team looked at a year of change history and found that almost every change touched all three. They regrouped them into one pricing service owned by one team, with tax exposed as a narrow call. Releases no longer needed coordination, and lead time for pricing changes dropped sharply.
Questions to ask
- When this changes, what else has to change and be released with it?
- Which kinds of coupling do we have here — data, temporal, deployment or semantic?
- Are these parts in one module because they change together, or because they are the same technical layer?
When not to use it
- Early prototypes, where you do not yet know what changes together; premature splitting guesses wrong.
- As a single metric, since coupling counts say little without knowing which changes matter to the business.
How it misleads you
Chasing zero coupling. Some coupling is the point of a system: parts must work together to deliver anything. The goal is coupling that is intentional, visible and placed where change is rare. Splitting a cohesive module to reduce "coupling" often just moves it into the network, where it is harder to see.
Further reading
Last reviewed · Suggest an improvement