Over the last decade, "Microservices" became the default architectural buzzword. Startups with two engineers and twenty daily active users were creating thirty microservices running on Kubernetes clusters.
A few months later, reality hits:
- A simple user checkout requires tracing RPC calls through four different services.
- Database consistency requires complex Saga orchestrators.
- Local development requires Docker Desktop consuming 16GB of RAM.
- CI/CD deployment pipelines take 45 minutes to run.
Before you jump into the distributed systems swamp, there is a vastly superior starting architecture that 90% of development teams should adopt: the Modular Monolith.
The Hidden Tax of Microservices
Microservices do not solve architectural problems; they turn architectural problems into distributed systems problems.
Single Monolithic Call:
Function A() -------- (In-Memory Pointer Call: 5 nanoseconds) --------> Function B()
Microservice Network Call:
Service A --(Serialize JSON)--> [TCP / TLS] --> [Router] --> [Service B] --(Deserialize)--> DB
(Total Latency: 25 milliseconds = 5,000,000x slower!)
When you split an application prematurely:
- Network Fallibility: Network packets drop. Services timeout. You now need Circuit Breakers, Retries, Idempotency Keys, and Dead Letter Queues for basic operations.
- Data Consistency: You lose single-database ACID transactions. Joining data across two tables now requires in-memory application joins or asynchronous event sync.
- Operational Drag: Instead of monitoring one binary, your team spends half its week maintaining Kubernetes ingresses, Helm charts, Service Meshes, and Docker registries.
What Is a Modular Monolith?
A Modular Monolith is a single deployable application binary whose codebase is rigorously structured into isolated domain modules with strict public interfaces.
+--------------------------------------------------------+
| Application Binary (Single Process, Single DB) |
| |
| +--------------------+ +--------------------+ |
| | Identity Module | <====> | Billing Module | |
| | (Internal DB Sch) | API | (Internal DB Sch) | |
| +--------------------+ +--------------------+ |
| ^ ^ |
| | | |
| v v |
| +--------------------------------------------------+ |
| | Catalog & Orders Module | |
| +--------------------------------------------------+ |
+--------------------------------------------------------+
The Golden Rules of Modular Monoliths:
- Modules Communicate via Public Interfaces Only: Module A never directly queries Module B's internal database tables or internal classes.
- Logical Database Isolation: Each module owns its designated tables or database schema. Foreign keys across module boundaries are forbidden!
- Single Process Deployment: Everything compiles into one binary and deploys to one server in seconds.
Summary
Start with a Modular Monolith. Keep your deployments simple, your transactions local, your latency in nanoseconds, and your developer productivity high. Only break things apart when scale demands it.

Top comments (0)