Modular Monolith vs Microservices: Choosing for Change

August 12, 2026

Modular Monolith vs Microservices: Choosing for Change

“Monolith or microservices?” is often treated as a question of technical maturity. It is more useful to treat it as a question about boundaries, ownership, and the cost of change.

A modular monolith and a microservice system can share the same domain model. Their main difference is whether boundaries are enforced inside one deployment or across a network.

Start with the forces

Before choosing a topology, identify what is actually creating pressure:

  • Do parts of the system need to scale independently?
  • Do teams require independent release schedules?
  • Are reliability or regulatory boundaries different?
  • Is one workload disrupting the rest of the application?
  • Can the organisation operate multiple services well?

If the answer is mostly “not yet,” separate deployment units may add more cost than value.

What a modular monolith gives you

A well-designed modular monolith keeps domain boundaries explicit while retaining simple transactions, local calls, one deployment pipeline, and straightforward debugging.

The word modular is doing the important work. Modules should own their data and expose deliberate interfaces. Code in one module should not reach through another module's persistence layer simply because the database is shared.

This structure creates an extraction path without paying distributed-systems costs on day one.

What microservices make explicit

Services provide strong runtime and deployment isolation, but every local assumption becomes a distributed-systems decision:

  • calls can time out after the remote side succeeds;
  • messages can be delivered more than once;
  • data is no longer changed in one transaction;
  • deployments require compatibility across versions;
  • tracing and correlation become essential.

These are manageable constraints when independent scaling, ownership, or reliability justifies them. They are waste when introduced only to make the architecture look modern.

A pragmatic extraction approach

I prefer to establish domain boundaries in-process first, then extract only where evidence supports it:

  1. Define module ownership and public contracts.
  2. Prevent cross-module database access.
  3. Record domain events at meaningful state transitions.
  4. Measure scaling, reliability, and delivery bottlenecks.
  5. Extract the boundary whose independent operation produces a clear benefit.

An outbox can bridge the transition when a local domain event needs reliable external publication. Consumers must still be idempotent because delivery is normally at least once.

The decision rule

Choose the architecture that makes the next several years of change safer for the team that will operate it. A modular monolith is not a temporary embarrassment, and microservices are not an automatic promotion. Both are tools for managing boundaries; the right choice is the one whose operational cost matches the problem.

GitHub
LinkedIn