Skip to content
Armin Shaikhy

[ ARTICLE_006 ] / MONO_ARCH

The Monolith Is Not the Problem

Why monolithic applications get blamed for organizational problems, and when a single deployable is still the right architectural choice.

The monolith became a pejorative. Teams rewrote working software into distributed systems to escape the word, not the underlying problem. Most of those rewrites made things worse.

A monolith is a single deployable unit. That is a description, not a diagnosis.

What a Monolith Actually Is

A monolithic application runs as one process. All modules share memory, a single database connection pool, and a unified deployment lifecycle. The code may be well-structured or a mess. The architecture does not determine that.

The conflation of “monolith” with “big ball of mud” is a category error. You can have a well-modularized monolith and a tangled distributed system. Structure is a code concern. Deployment topology is a separate concern.

Deployment Simplicity as a Feature

One artifact. One deployment pipeline. One rollback target.

When something breaks in production, a monolith has one set of logs, one runtime, and one process to inspect. The failure surface is bounded. Debugging distributed systems requires correlating traces across service boundaries, reconciling clocks, and reasoning about partial failures. That complexity has a cost every time something goes wrong.

Simplicity is not a consolation prize. It is a durable engineering advantage.

Shared Memory, No Network

Within a monolith, module A calls module B through a function call. The call is fast, typed, and transactional. If module B fails, the error propagates immediately through the same stack.

Split those modules into services and the call becomes an HTTP request or a message. It is now subject to network latency, serialization overhead, partial failure, and retry logic. Every service boundary introduces a new failure mode that did not exist before.

That trade-off is sometimes worth making. It is never free.

The Real Cost of Distributed Systems

Distributed systems require infrastructure that monoliths do not:

  • Service discovery
  • Load balancing per service
  • Distributed tracing
  • Circuit breakers and retry budgets
  • Eventual consistency handling
  • Independent deployment pipelines for each service

Each of these is a real operational burden. Small teams routinely underestimate it until they are maintaining fifteen services and the on-call rotation is worse than before.

When to Stay Monolithic

A monolith is the right call when:

  • The team is small (fewer than two pizza teams per module)
  • Deployment frequency is uniform across the codebase
  • Data ownership does not divide cleanly along service lines
  • The product is early and the domain model is still changing

Conway’s Law runs in both directions. Distributed systems reflect distributed teams. If the organization is not distributed, the architecture does not need to be.

When to Leave

Some signals genuinely indicate it is time to extract:

  • One subsystem has a deployment cadence and scaling profile completely unlike the rest
  • Independent teams are blocked on each other because of shared code ownership
  • Regulatory or compliance requirements demand isolation at the data layer
  • A specific component has a resource profile (CPU, memory, I/O) that cannot be addressed without isolating it

Extract the module that needs to be different. Keep the rest together. Partial decomposition is a valid and often permanent state.

The goal is software that ships and runs reliably. The deployment topology is a means to that end, not the end itself.

Shared Tags