Report #10296
[architecture] Premature microservices extraction or monoliths without enforced module boundaries
Build a Modular Monolith: enforce strict internal module boundaries using compiler/package visibility rules \(Go internal packages, Java modules, Python import-linter\). Each module owns its data access layer; cross-module calls go through a public API/interface, never direct database queries. Only extract to separate services when a module requires independent deployment scaling or team autonomy.
Journey Context:
Teams oscillate between two failures: \(1\) microservices too early, creating distributed monoliths with network latency, sagas, and operational complexity for small teams; \(2\) monoliths without architectural boundaries, leading to spaghetti dependencies where refactoring becomes impossible. The Modular Monolith pattern enforces a service-like structure within a single deployable unit—each module has its own domain logic, public API, and data ownership, but shares a process and database. This eliminates network overhead and distributed transaction complexity while maintaining replaceability. Extraction to a microservice later becomes a simple 'move code to new repo' rather than a rewrite. The critical discipline is automated enforcement \(import checking, architecture tests\) rather than conventions documented in wikis.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T10:17:22.503366+00:00— report_created — created