
✅ matplotlib version: 3.10.8
✅ Setup complete!
🎨 Configuration loaded
Software engineers love to talk about architecture in qualitative terms.
But beneath those instincts lies something far more concrete
For the first six months, even a year, everything felt fast. Our Ruby-on-Rails application was humming along and new features were added daily
Then, something strange started happening; it began to shift:
Then the real symptoms appeared:
Eventually they hire an architect, who spends some time with the codebase(s) and running various tools
Your problem isn’t Rails. Your problem is coupling.
All the software engineers had heard of this, of course, but thought of it as a qualitative measurement. It may have come up a few times since, but had never been exactly quantified. Now here it is in the real world.
The application had quietly evolved into something infamous:
It’s a simple complex system. Because it’s simple, it’s prone to cascades, and because it’s complex, you can’t predict what’s going to fail. Or how. – “The Expanse”
Note: Coupling can still be a huge problem even if the software in question is not a monolith
When software is tightly coupled

Nearly every structural coupling metric derives from two simple counts.
Who depends on me?
↑
Ca
│
● GIVEN MODULE/PACKAGE
│
Ce
↓
Upon whom do I depend?
Ca = number of external modules that depend on this one
Afferent coupling measures responsibility.
If many modules depend on you, your stability matters.
Break this module, and others break too.
Modules with high Ca become structural anchors.
Ce = number of external modules this module depends on
Efferent coupling measures vulnerability.
The more dependencies you have, the more ways your code can break.
Every dependency introduces:
Dependencies are powerful.
But they are never free.
These metrics behave like a financial balance sheet.
| Metric | Analogy |
|---|---|
Ca (Afferent Coupling) |
Creditors (who depends on you) |
Ce (Efferent Coupling) |
Debts (who you depend on) |

From Ca and Ce we derive a powerful ratio.
𝐼 = 𝐶ₑ / (𝐶ₑ + 𝐶ₐ)
Instability ranges from 0 to 1.
| I Range | Stability | Meaning | Change Strategy |
|---|---|---|---|
| 0.0 ≤ I < 0.25 | Stable | Many dependents, few dependencies | Change with care |
| 0.25 ≤ I < 0.50 | Balanced | Healthy structural position | Normal dev pace |
| 0.50 ≤ I < 0.75 | Borderline | Dependency heavy | Monitor closely |
| 0.75 ≤ I ≤ 1.0 | Unstable | Few dependents, many dependencies | Refactor freely |
The graph below shows how instability changes as Ce grows for different fixed values of Ca.
Low Ca produces curves that rise very quickly toward volatility. Higher Ca dampens that rise, making the same increase in Ce less destabilizing.
This leads to one of the most important architectural principles.
Dependencies should flow toward stability.
unstable modules → stable modules
When stable modules depend on unstable ones, architectural fragility appears quickly.
The chart above shows how Instability changes as Ce grows for several fixed values of Ca.
A few patterns jump out immediately:
Ca = 0 line is the extreme case.
A module with no dependents is structurally free to become maximally unstable.This is why Ce is not the whole story by itself. The same number of outgoing dependencies means something different depending on how much responsibility the module already carries.
Said another way: instability is not merely about how much you depend on — it is about that dependency load relative to who depends on you.

The instability curves plot the ratio I = C_e / (C_e + C_a) as the number of efferent couplings (C_e) grows for a series of fixed afferent coupling counts (C_a). Each curve shows how quickly a module will move from stable toward volatile as it accumulates outgoing dependencies. When C_a is small, even a handful of efferent couplings causes I to rise sharply, meaning that leaf modules become unstable very quickly. When C_a is large, the curves climb more gradually — a stable core module with many incoming dependents can tolerate more outgoing dependencies before becoming volatile. In other words, high‑responsibility modules (large C_a) have more structural inertia against instability, while low‑responsibility modules rapidly drift into the volatile region as they add dependencies. The metric I was defined by Robert Martin as the ratio of efferent coupling to total coupling and measures a package’s resilience to change: I = 0 indicates complete stability and I = 1 indicates complete instability.
This metric differentiates types as concrete or abstract (interface/protocol/port).
A = Na / Nc
Na = number of abstract typesNc =`total number of typesA = 1 → completely abstractA = 0 → completely concreteWhen plotting Abstractness (A) against Instability (I), something interesting appears.
Healthy modules tend to cluster along a line defined by:
A + I = 1
This line is called the Main Sequence.
The conceptual graph below shows the terrain first:
The key idea is simple: modules do not have to sit exactly on the main sequence, but the farther they drift from it, the more likely they are to be structurally imbalanced.

low A
low I
Meaning:
concrete AND stable
These modules are depended on by many other modules but contain little abstraction.
Examples often include:
Changing them causes cascading impact.
Hence the name.
high A
high I
Meaning:
abstract AND unstable
These modules contain abstractions nobody uses.
Example:
12 interfaces
1 implementation
0 dependents
Beautiful architecture.
No real purpose.
Once we place real modules on the same chart, the picture gets richer.
The detailed graph below shows:
D) for the more interesting examplesThat lets us see not just where a module sits, but how far off-balance it is.
Some modules live outside the danger zones and are still worth watching. A service layer, API gateway, or shared utility package may not be pathological, but a non-zero distance still suggests the design is drifting away from the ideal balance.

✅ Markdown exported to coupling-article-part1.md
✅ Exported 3 output asset(s)
PosixPath('coupling-article-part1.md')
These metrics apply to almost any software system:
libraries
A tightly coupled monolith
Architecture is often treated as an art.
But beneath the diagrams lies something more mechanical.
Software systems obey structural forces.
Coupling is one of them.
And like gravity…
you can ignore it.
But you cannot escape it.