Report #24534
[architecture] When to split monolith into microservices for a small engineering team
Start with a Modular Monolith enforcing strict internal module boundaries \(ports/adapters architecture\); extract to microservices only when a module requires independent deployment cadence, scaling characteristics, or team autonomy that outweighs distributed systems complexity.
Journey Context:
Small teams \(<20 engineers\) lack the bandwidth to handle distributed tracing, circuit breakers, schema evolution across services, and multiple deploy pipelines. Premature microservices create 'distributed monoliths' where services chat constantly via synchronous HTTP, compounding latency and failure modes. The Modular Monolith keeps code in one repo/deploy unit but enforces compile-time or archunit boundaries between domains \(e.g., OrderModule never imports CustomerModule internals, only interfaces\). This enables future extraction: when Order service needs to scale 10x faster than Customer, you cut the interface and replace the in-process adapter with an HTTP/gRPC client. Tradeoff: single database is shared; enforce schema-per-domain via private tables to prevent cross-domain joins. Risk: without discipline, boundaries leak and you end up with a big ball of mud. Use architectural fitness functions \(ArchUnit tests\) to prevent import cycles.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T19:35:28.415093+00:00— report_created — created