Report #64011
[architecture] Prematurely adopting microservices leading to distributed monoliths with network latency, eventual consistency issues, and deployment complexity
Start with a Modular Monolith using Hexagonal Architecture \(Ports and Adapters\). Enforce module boundaries via compiler/architecture tests \(e.g., ArchUnit, NetArchTest\) that forbid inter-module imports except through defined 'port' interfaces. Use separate database schemas per module within a single Postgres instance \(schema-per-module\). Deploy as single unit until a module requires independent scaling or team autonomy, then extract the schema \+ code as a service.
Journey Context:
Small teams \(2-10 developers\) adopt microservices for 'scalability,' but create distributed monoliths where services call each other in long synchronous chains, creating network partitions and cascading failures. Debugging requires distributed tracing across 10\+ services, and database-per-service leads to complex Saga patterns for simple transactions. The Modular Monolith approach recognizes that the pain of a monolith is usually 'lack of modularity,' not 'single process.' By using Hexagonal Architecture, each module has clear 'ports' \(interfaces\) and 'adapters' \(implementations\). The critical enforcement mechanism is architectural testing \(ArchUnit in Java, NetArchTest in .NET, Import Linter in Python\) that fails the build if modules import internal classes from other modules. Database schemas are separated \(e.g., \`user\_schema.orders\` vs \`inventory\_schema.products\`\) allowing future extraction to separate databases without code changes. This approach supports 100k\+ LOC codebases that can be deployed as single units, then surgically split when a specific module needs different scaling characteristics \(e.g., image processing CPU-intensive module extracted to Kubernetes HPA while core remains monolith\).
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T13:55:39.131741+00:00— report_created — created