Modular monolith boundaries
Measure the changes that cross module boundaries
Dependency counts are useful signals, but the practical question is whether ordinary business changes remain understandable and local. Review actual change patterns.
In this article
Choose representative changes
Look at recent work such as adding an order status, changing an approval rule or introducing a billing adjustment. Record which modules changed and why each dependency was necessary.
A feature that legitimately spans a workflow may touch several modules. That is not automatically poor design. The concern is repeated changes to unrelated internals because callers depend on storage fields or implementation details they should not own.
Use examples alongside counts. A metric showing five touched modules says little without the nature of the change.
Track boundary violations separately
Count prohibited imports, direct cross-module writes and dependency cycles caught by the normal checks. Record exceptions and their owners rather than hiding them in an allowlist nobody reviews.
Distinguish a reporting read from a mutation dependency. Both cross data boundaries, but they create different coupling and authority concerns. A single undifferentiated database-access count can encourage the wrong fixes.
Track how long exceptions remain and whether new work adds more. An old debt entry may be acceptable temporarily, while an increasing pattern suggests the public contract is not meeting callers' needs.
Observe development and testing effort
Measure whether a module's public behaviour can be tested without setting up unrelated internals. Record where fixtures require broad application knowledge or where a small change breaks distant tests.
These are diagnostic signals, not universal performance targets. A complex shared business invariant may legitimately require wider integration testing. The review should explain that relationship rather than optimise for an arbitrary number of isolated tests.
Look at review ownership too. If every change requires the same few people to understand the whole codebase, the module boundaries may not align with maintainable responsibilities.
Use the evidence to improve contracts
Repeated cross-boundary changes can indicate a missing operation, a misplaced rule or a boundary drawn through data that needs to change together. Fix the underlying contract before adding more dependency exceptions.
Compare the next few similar changes after the refactor. Did callers need fewer internal details? Did the business rule remain in one place? Did the public API become clearer?
A modularity assessment is useful when it explains why work spreads and shows whether a change reduced that coupling. A low dependency count alone does not establish a good architecture.
Primary sources
Microsoft Learn: common web application architecturesMartin Fowler: Monolith FirstReferences checked 11 September 2026.