DEV Community

Cover image for Distributed Monolith: When Microservices Are Just a Monolith with Network Latency
overthelex
overthelex

Posted on • Originally published at legal.org.ua

Distributed Monolith: When Microservices Are Just a Monolith with Network Latency

You split your code into services. You have separate containers. You even have a gateway. So why does deploying one service still break the other?


What is a distributed monolith

A distributed monolith is an architecture that looks like microservices but behaves like a monolith. Services are separated at the code level but remain coupled at the infrastructure, data, or deployment level.

Classic symptoms:

  • Shared database – different services read/write to the same PostgreSQL instance
  • Shared library without versioning – a change in a common package breaks everyone simultaneously
  • One docker-compose – all services are deployed together, even if only one changed
  • Synchronous HTTP calls – service A cannot function if service B is unresponsive
  • Shared cache – one Redis for everyone, LRU eviction from one service kills another's cache

Sound familiar? That's our architecture. And we believe that right now – it's the right choice.


When a distributed monolith is the right choice

Here's an unpopular opinion: a distributed monolith isn't always a problem. At a certain scale, it's the optimal architecture.

Benefits we get

1. Operational simplicity – One docker compose up brings everything up.

2. Development speed – A shared package means DRY.

3. Transactional integrity – One PostgreSQL = the ability to JOIN across schemas.

4. Debuggability – One docker compose logs shows the entire request flow.

5. Cost – One server instead of three.

The formula: when a distributed monolith is enough

Team < 5 developers, load < 1000 RPS, deploys < 5/day, one server handles it, no requirements for independent scaling.


Step-by-step evolution plan

Phase 1: Hardening (effort: low, impact: 80%)

  • Split Redis into separate instances per service
  • Version the shared package with semver
  • Add circuit breaker in RemoteServiceClient

Phase 2: Infrastructure independence

  • Separate PostgreSQL instances
  • Split docker-compose per service
  • API contracts between services

Phase 3: True microservices (team > 5)

  • Service discovery instead of env vars
  • Message queue for async operations
  • Independent CI/CD pipelines

Conclusion

A distributed monolith is not a diagnosis. It's a stage in architectural evolution. 80% of microservice benefits can be achieved with 20% of the effort – by splitting Redis, adding a circuit breaker, and versioning your shared package.


Sign up: legal.org.ua


Originally published on legal.org.ua.

Top comments (0)