Replaceability Test
also called Swap Test, Modularity Evidence
The evidence-based check for whether a boundary is real - not how many services exist, but whether one implementation could be swapped without touching the others, and whether it ever has been.
Counting deployable units measures nothing. Twelve services that share one database, deploy in a fixed order, and break together are twelve deployables and one module — with a network in the middle.
The test is replaceability: could this component be swapped for a different implementation without changing the others? And better: when did you last do it, and what did it cost?
Why it matters
Boundaries that exist only in a diagram fail exactly when you need them — during a vendor migration, a performance rewrite, or an incident that requires isolating a component. The attempt is when teams discover that the interface was a projection of the implementation and everything downstream depends on details it was supposed to hide.
Implementation patterns
- Make the interface narrower than the implementation. If the API exposes every field of the internal model, there is nothing encapsulated and the interface will change whenever the model does.
- Write a second implementation early, even a trivial one — an in-memory fake, a stub provider. It is the cheapest possible proof that the boundary is real, and it doubles as a test fixture.
- Route through the interface in production, not just in tests. Boundaries only enforced in test code are routinely bypassed in the real path.
- Check for independent deployability, which is the operational form of the same property: can one team deploy and roll back without telling the others?
- Check comprehensibility in isolation: can a new engineer understand this module without reading the others?
Industry example
A platform such as Supabase composes Postgres, auth, storage, realtime and a generated data API. The shared Postgres substrate is simultaneously its greatest strength and the largest threat to its modularity. The strength is real architecture: one row-level-security mechanism enforcing authorisation across storage, realtime and the data API is an enormous simplification and puts one policy behind one enforcement point.
The threat is that shared substrate invites shared state. The discipline is treating "we both use Postgres" as an infrastructure fact rather than permission to read each other's tables — and the way you know whether that discipline held is by asking what it would cost to run the realtime component against a different source of change events.
Failure scenarios
- The interface leaked the implementation, so the swap requires changing every consumer.
- Boundaries enforced only in tests, bypassed in the production path.
- A shared substrate silently became shared state, so components are coupled through data rather than through interfaces and nothing in the code shows it.
- Deployment order dependencies, which prove the components are not independent whatever the diagram claims.
Trade-offs
Genuine replaceability costs abstraction, and abstraction costs directness. An adapter layer between your code and a database you will never change is pure overhead — it adds indirection, obscures the query, and defends against a scenario that will not occur.
Reserve replaceability for boundaries where change is plausible: third-party providers, anything with a contract renewal date, anything with a known scaling ceiling, anything a competitor might do better. For everything else, directness is the better default and the boundary can be introduced when the need appears.
Interview question
"Your architecture diagram shows six clean components. How would I verify, without asking you, that those boundaries are real? What would I look at in the repository and in the deployment history?"