ngpaas.eu

Microservices vs. Monolith: Which Fits Your Team?

Microservices or monolith? An honest comparison of complexity, scaling, team size and cost, and why a modular monolith is often the best start for small teams.

Cloud-nativePublished

For most small and mid-sized teams a modular monolith is the better choice: one application, one deployment, with clean internal boundaries. Microservices make sense when several teams need to release independently or when parts of a system have very different load profiles. The decision is less about technology than about team structure and operating effort.

The two models

Monolith. The whole application is built, tested and deployed as one unit. It typically shares one database. Calls between parts of the application are function calls in the same process.

Microservices. The application is split into small services, each with its own codebase, deployment pipeline and, ideally, its own data store. Services communicate over the network, via HTTP APIs or message queues.

Modular monolith. The middle path: one deployable unit, but internally divided into modules with explicit interfaces and no shared access to each other’s tables. It is the most practical starting point for most teams.

Comparison

Aspect Monolith (modular) Microservices
Deployment One pipeline, one artefact One pipeline per service
Local development Start one app Start many services or mocks
Calls between parts In-process, fast, transactional Over the network, can fail or be slow
Data consistency One database, transactions Distributed data, eventual consistency
Scaling Whole app scales together Each service scales independently
Team autonomy Shared codebase, coordinated releases Teams own and release their services
Operations Fewer moving parts Orchestration, service discovery, tracing
Typical fit One or a few teams Many teams, large systems

The hidden cost of microservices

Splitting an application does not remove complexity, it moves it into the infrastructure. Each additional service needs its own build, deployment, configuration, logging, metrics and alerting. Calls that used to be function calls become network requests that need timeouts, retries and versioned APIs. A transaction across two services is no longer a database transaction but a coordination problem.

In practice, this usually means that a microservice architecture needs a platform to run on, typically Kubernetes plus tooling for observability. For a team of three to ten developers, that overhead can easily consume more time than it saves. Our guide to container deployment for small teams shows lighter options.

When microservices make sense

Microservices are a good fit if several of these apply:

  • Several teams work on the system and block each other with shared releases.
  • Very different scaling needs: one component, such as image processing, needs many times the resources of the rest.
  • Different technical requirements: a part needs another language, runtime or hardware, for example GPUs.
  • Isolation: a component handles sensitive data and should run separately with its own access rules.
  • Mature operations: you already have automated deployments, central logging, tracing and on-call routines.

If none of these applies, the monolith is not a compromise but the more economical choice.

How to build a good modular monolith

  1. Cut modules along business domains, not technical layers. ‘Orders’, ‘billing’ and ‘customers’ are modules; ‘controllers’ and ‘repositories’ are not.
  2. Define public interfaces for each module and forbid direct access to another module’s internals or tables.
  3. Keep data ownership clear. Each table belongs to one module.
  4. Automate tests and deployment from day one, as described in what cloud-native means.
  5. Measure. Logs and metrics per module show you early which part might need to become a separate service.

With these rules, extracting a module later is a contained project rather than a rewrite.

Where to run it

A monolith in a container runs well on a PaaS, which builds and deploys it from Git and scales by adding instances. The question of where to run is covered in PaaS vs. IaaS vs. serverless. If you later extract services, the same PaaS can often host them too, before Kubernetes becomes necessary.

Migrating from microservices back

Some teams that started with microservices merge services again because the overhead outweighs the benefit. That is a legitimate decision. Start by combining services that always change together and share data, deploy them as one unit and keep the module boundaries in the code.

Frequently asked questions

What is a modular monolith?

A single deployable application whose code is divided into clearly separated modules with defined interfaces, for example billing, users and catalogue. Modules do not reach into each other's data directly. It keeps the simplicity of one deployment while preparing for a later split.

When should we split off a microservice?

When a concrete problem justifies it: a component needs a different scaling profile, a separate team wants its own release cycle, or a part must be isolated for security or compliance reasons. ‘Because it is modern’ is not a reason.

Are microservices more reliable?

Not by default. They can isolate failures, but they also add new failure modes such as network timeouts and partial outages. Reliability comes from timeouts, retries, monitoring and testing, whichever architecture you choose.

Can a monolith scale?

Yes. You can run several instances of the same application behind a load balancer and scale the database separately. Many large web applications run as monoliths for years.

More in Cloud-native