Java Omnibus
OOAD & Architecture / Architectural Styles / Monolith vs Modular Monolith vs Microservices
Monolith Modular Monolith Microservices Java Evolution
Architectural Styles

The most important distinction is not monolith versus microservices. It is whether the boundaries are real.

A monolith can be elegant or chaotic. A microservice system can be well-bounded or painfully distributed. The more useful progression is often monolith, then modular monolith, then microservices only when the boundaries and operational need are both proven.

Why This Topic Matters

Why it matters in real Java systems

Many Java teams inherit a single deployable application and feel pressure to split it immediately. But if the internal boundaries are weak, the split just exports confusion into the network. A modular monolith is often the most responsible middle step.

Core Explanation

The main architectural idea

A plain monolith packages everything together, often with one deployable unit and one operational surface. A modular monolith keeps that deployment simplicity but enforces stronger internal module boundaries. Microservices add independent deployment and operational isolation, but they also add distributed systems costs: latency, retries, observability, consistency, contracts, and platform overhead.

The usual healthy path is to build strong internal modules first. If those modules later need independent scaling, release cadence, ownership, or runtime isolation, a microservice split becomes far less risky.

Concept Breakdown

Key ideas to keep in mind

Concept

Monolith

Simple deployment surface, but boundaries are often accidental unless deliberately enforced.

Concept

Modular monolith

One deployment, strong internal modules, and a much better training ground for future distribution.

Concept

Microservices

Independent deployability and isolation, but with real distributed systems costs that only pay off when the need is real.

Comparison table

Comparison table

Option Main strength Main risk
MonolithOperational simplicityBoundary erosion and tight coupling
Modular monolithStrong internal structure with simple deploymentRequires discipline because the compiler and runtime do not enforce every module rule automatically
MicroservicesIndependent deployment and scalingDistributed coordination, consistency, and platform complexity
Java Example

Java example in the Order Management domain

Java example: modular package boundary instead of immediate network split
package org.javaomnibus.ecommerce.orders;

public interface OrderApplicationApi {
    OrderSummary place(PlaceOrderCommand command);
    OrderSummary find(String orderId);
}

package org.javaomnibus.ecommerce.shipments;

public interface ShipmentApplicationApi {
    ShipmentSummary plan(String orderId);
}
Code Walkthrough

Step by step

  1. The modules expose explicit application APIs even while living in one deployable system.
  2. This creates a cleaner internal architecture than directly calling concrete classes across the whole codebase.
  3. If a later split becomes necessary, these APIs are a better starting point than tangled internal calls.
  4. This is why modular monoliths are often such a strong intermediate architecture.
Real-World Usage

Where this helps in practice

  • Refactoring large Java monoliths that need better internal boundaries
  • Choosing a platform shape for multiple collaborating business capabilities
  • Delaying premature microservice splits while still improving architecture
Trade-Offs

Trade-offs and when not to overuse it

  • A modular monolith does not remove the need for discipline. It just lets you practice that discipline without network complexity.
  • Microservices are excellent when justified, but punishing when adopted early.
Common Mistakes

Frequent mistakes to watch for

  • Calling a codebase a modular monolith when any package can call any other package freely
  • Splitting into services before the business boundaries are stable
  • Equating number of deployables with architectural maturity
  • Leaving shared libraries as hidden coupling points across services
Related Pages

Related concepts


What To Read Next