Start a project
Software Engineering

Monolith vs microservices: what actually makes sense?

Service boundaries are an organisational decision with a technical bill attached. Most teams pay the bill before they need the benefit.

Author JANNEX Engineering
Published 25 June 2026
Updated 28 July 2026
Reading time 7 minutes
Key takeaway

Start with a well-structured monolith and clear internal module boundaries. Extract a service when a specific part has a genuinely different scaling profile, release cadence or ownership — not because the architecture diagram looks better.

What splitting actually costs

A distributed system replaces function calls with network calls. Everything that was previously guaranteed becomes something you have to engineer.

  • Calls now fail partway, so retries, timeouts and idempotency become mandatory
  • Transactions no longer span the operation, so you are writing compensation logic
  • Debugging requires distributed tracing to answer questions a stack trace used to answer
  • Each service needs its own pipeline, monitoring, alerting and on-call coverage
  • Local development becomes an exercise in orchestration

None of these are unsolvable. All of them are ongoing costs, and they are paid whether or not the benefits arrive.

Three things that justify a service boundary

  1. A different scaling profile. One component needs ten times the capacity of the rest, or needs hardware the rest does not — a video encoder, a model inference path, a bulk import.
  2. A different release cadence. A component that must ship several times a day held back by a system released weekly, or the reverse.
  3. A different owner. A separate team with real accountability for the component. Conway's law is not a warning here; it is the actual justification.

Absent one of these, a module boundary inside a single deployable gives most of the benefit and none of the operational cost.

The version that keeps your options open

A modular monolith is a single deployable with strict internal boundaries: modules that communicate through defined interfaces, do not reach into each other's tables, and could be lifted out without unpicking the rest.

This is the position of maximum optionality. Splitting later is then a mechanical exercise rather than an archaeology project — and in a great many cases you will find you never need to.

The database is the real boundary

Teams routinely split services while leaving them sharing one schema. That produces the operational cost of microservices with the coupling of a monolith — the worst available combination.

If a service does not own its data, it is not a service. If splitting the data is unacceptable — because you need transactional consistency across it — that is a strong signal the boundary is in the wrong place.

Where to start

For nearly every new system: one deployable, strict module boundaries, one database with clear ownership per schema, a real pipeline and real observability from the beginning. Extract when a specific, nameable pressure appears. Architecture earned that way is defensible; architecture chosen in advance usually is not.

Related capability

Software Engineering

Most software does not fail at launch. It fails eighteen months later, when a reasonable change turns out to cost more than the original build.

Software Engineering
Next

Working on this problem?

The conversation is usually more useful than the article. Tell us the constraint you are working against.

Or write to connect@jannex.in