StyleChapter II · Styles & patterns · Building block 2 of 8

Modular monolith

A modular monolith consists of delimited modules in a shared application. Module contracts protect responsibilities within the process.

  1. ModuleDelimited business responsibility with own contract.
  2. A deploymentAll modules are built and delivered together.
  3. CentreBoundaries as in services, operation as in a monolith.

Context

Why this is important

The modular monolith is the middle between Big Ball of Mud and microservices: clear business boundaries, but without distributed operation. How boundaries are enforced, shows the building block module boundaries; here it is about the choice of style.

This building block explains business modules for joint delivery. For independently operated services, see Microservices.

At a glance · Modules in joint deployment

Modules A, B and C are located in a deployment and only address each other via public interfaces; each has its own scheme.
Shop example · Form comparison

The same shop in three forms

The outgoing shop delivers catalogue, shopping cart, order, payment, warehouse, shipping and invoice together. Only the payment provider is outside.

This is how you read the picture

  1. Module The seven shop modules catalog to invoice, each with clear task.
  2. A deployment The dashed area ‘1 Deployment" and the key figure Deployments: 1 instead of 7.
  3. Centre In modular monoliths, transaction and border check are both marked green.

Seven modules with contracts in a shared application.

Deployments
1
Network calls in the checkout
None
Ordering and reservation in a transaction
Yes
Boundaries enforced by
Architectural test
Error of a module
Meets the whole process

Order reserved via the contract in stock and booked locally in a transaction. A test reports unauthorized access immediately.

Values illustrative

Choose a shape; card and key figures alternate. Values are illustrative.

Benefits & limitations

Helps if:

  • Clearly bounded business areas gain explicit module contracts and can be deployed together.
  • Local calls and transactions keep flows simple; clear data ownership limits ensure the responsibility of the modules.
  • A shared deployment lets teams test module boundaries and gradually establish independent operational ownership.

Boundaries

  • No error isolation: A memory leak in one module brings the whole shop to a standstill.
  • One scaling unit: load on Catalogue requires scaling all modules together; measure demand per module.
  • A shared database invites shortcuts: boundaries quietly erode without checks. See Module Boundaries and Data Ownership.

In practice

  1. Give each module a clear business area of responsibility and keep its data internally. The contract is only intended to disclose the capabilities that other modules actually need.
  2. Check module dependencies and write access automatically. Other modules should request changes through the owning module's contract, keeping rules protected within a shared deployment.
  3. Measure the cost of shared releases and scaling. Separate runtime units when independent releases or load profiles justify the additional operational work. Bounded Context helps define domain boundaries; Data Ownership examines ownership in more detail.
Read the detailed explanation

A modular monolith groups modules with distinct business responsibilities in one application that is built and deployed together. Each module owns rules, internal data and a contract for permitted collaboration. The application may run as several replicas or include additional workers; the shared deployment unit remains the central operational boundary.

Data ownership and controlled module access establish the boundaries. Shared processes allow direct local calls and suitable local transactions. Contracts and automated dependency checks preserve the separation even when all modules are released together.

Module Boundaries identifies business responsibilities within the application; Data Ownership makes authoritative ownership and permitted changes explicit.

This form is also known as a Modulith. In Java applications, for example, Spring Modulith checks whether modules use only their permitted contracts. Shopify has publicly described its use of a modular monolith.

Check your understanding

Test yourself in three stages

  1. ReadingCheck in the picture

    What values does the picture give for deployments and network calls in the checkout for modular monoliths?

    View the solution with justification

    One deployment and no network calls in the checkout. For microservices, there are seven deployments and several calls.

  2. ApplyingTransferred to a new situation

    The catalogue gets a lot more load at Christmas time. What does this mean in modular monoliths?

    View the solution with justification

    The application is a scaling unit, so all modules run up. First, measure how much load the catalog causes; only when this becomes expensive, is it worth separating.

  3. EvaluateWeighing an alternative

    The team does not want to check the limits for the time being, because everything is in a repo. How do you rate that?

    View the solution with justification

    Advantage: less effort at the beginning. Disadvantage: Without testing, boundaries quietly erode until the shop becomes the Big Ball of Mud. Recommendation: introduce an architectural test early, because it is cheap and keeps the option for later separation open.

Explore further

These optional deepenings complement the learning goal of this page.

Microkernel and plug-ins

A Microkernel keeps a small core stable and extends it through defined plug-in points. Plug-ins can add optional capabilities such as shipping rules or payment methods; contract versioning and fault isolation remain explicit design responsibilities. Sharing a process or deployment does not automatically provide fault or security isolation. This style suits systems where extensibility through interchangeable modules is a central goal.

For testingDefine a shipping-options plug-in contract for the shop core: describe extension points, supported contract versions and behaviour for incompatible plug-ins. Also check how a faulty plug-in is isolated and which effects remain possible within the shared process.