Coupling Depends on When, Not Just What
Here’s a general principle: the extent of coupling between two things depends not just on what one thing knows about the other, but also on when it knows it.
A Simple Example
We have two services — Service A and Service B. They both need to share some data.
They can share it one of two ways: through a shared library, or through an API.
Option one: a shared library
The data could live in a small shared library that both services import:
This works, and it’s nice to work with — you get type-checking, and can see exactly what the data looks like, at compile time.
Option two: an API
Instead, Service A could call an endpoint that Service B exposes, at runtime:
No library, no import. The data just lives in Service B, and Service A asks for it when it needs it.
Same information, different timing
Both options give Service A the exact same information — the same data. Nothing about what Service A knows changes between the two. What changes is when it finds out.
With the library approach, the data is bound at compile time. The value gets baked into Service A’s build output. If the data changes, Service A has to recompile, rebuild, and redeploy to pick it up — even though nothing about Service A’s own code actually changed.
With the API approach, the data is bound at runtime. Service A doesn’t know what the data is until it actually asks. If the data changes, Service A doesn’t need to do anything — the next call just returns the new value. No recompiling, no rebuilding, no redeploying.
That’s less coupling, and less maintenance — not because Service A knows less, but because it finds out about the data later.
Takeaway
It’s well understood that we should minimize coupling between two things, so a change on one side doesn’t force a change on the other. But coupling isn’t only about what one thing knows about another — it’s also about when it knows it. Binding the same information later is itself a way to reduce coupling, even when the information exchanged doesn’t change at all.