andregoepel.dev
Start a conversation
All posts
Software Architecture 5 min read

Microservices or a Modular Monolith? A Decision Guide for Mid-Sized Businesses

For me, the architecture question starts with the team's daily work: what is too difficult to change, release, or operate today? A modular monolith can provide a good foundation. Microservices become worthwhile when their independence solves a concrete problem and the team can support the additional operations. The deciding factor is the benefit you actually need.

.NETSoftware ArchitectureMicroservicesModular Monolith

Name the problem first

“We need a modern architecture” is an understandable ambition. It is too vague to guide a decision.

More useful statements are: “Reporting slows down order entry.” Or: “Three teams wait for each other at every release.” You can investigate these problems, set objectives, and later check whether a change helped.

My opening question is therefore: which specific constraint should splitting the application into services remove? If the answer mainly consists of technology names, there is more analysis to do.

What a modular monolith means

A modular monolith is released as one application, but its internals are organized around business responsibilities. Orders, billing, and customer management have defined interfaces. A module cannot freely reach into another module's internals.

Separate projects can support those boundaries in a .NET application. Creating them does not establish the boundaries by itself. What matters is which dependencies are allowed, who owns the data, and whether the rules hold up in everyday development.

A shared database server is possible. That does not mean every module should be allowed to change every table. Technical proximity should not erase business ownership.

Microservices additionally place those boundaries between separately operable services. This enables independent deployment. The application must also handle network failures, components with different availability, and distributed data. The Azure Architecture Center describes this trade-off.

Five questions to guide the decision

1. Who needs to release independently?

Look at recent releases: what actually delayed them? A shared deployment is not automatically the problem. Perhaps automated tests or a clear approval decision are missing.

However, if several teams regularly hold back completed changes because unrelated business areas share one release train, separate deployment is a serious candidate. Make the objective specific: which team will be able to ship which change without coordinating with the others?

2. Which part actually needs different resources?

“We need to scale” tells you little. Does an overnight import need a lot of memory while the portal needs short response times during the day? Or is a database query slow regardless of how many services sit in front of it?

I would measure first and locate the bottleneck. Moving a specific workload into a separate worker might already be the right answer. It does not require customer management, permissions, and billing to become separate services too.

3. Which data must be correct together?

Take a business process and walk through a partial failure. An order has been accepted, but reserving the stock has failed: what does the customer see? Who fixes the state? Can confirmation arrive later?

Answer these questions before splitting the system. A business requirement for a shared transaction is a reason to examine a boundary particularly carefully. Bringing data into agreement later can work when the process permits it and failure handling is designed in.

4. Who operates it the next morning?

The decision needs an accountable person or team when something goes wrong. Can they trace a failed workflow, roll back a problematic release, and identify the affected customers?

Martin Fowler identifies rapid deployment, monitoring, and close collaboration between development and operations as prerequisites for microservices. In planning terms, budget for that work from the start. A managed service does not take responsibility for your business process.

5. How confident are you in the business boundaries?

If every other new requirement changes the proposed split, I would test those boundaries inside one application first. Business uncertainty does not disappear when an HTTP connection separates two modules.

That is also the core of the Monolith First argument: understand the boundaries better, then distribute if necessary. It does not promise that extracting a service later will be free. That work still needs its own plan.

An example: a customer portal with expensive reporting

Suppose one team maintains a customer portal. Customers manage orders, employees process them, and a monthly report occasionally consumes substantial computing resources. This is a hypothetical example.

My initial design would be a modular application. Before splitting it, I would measure whether the report actually affects interactive use and identify the cause.

If separate processing helps, a worker could take over reporting. The team would need to decide how fresh its data must be, how jobs are retried, and where the completed result is stored. The rest of the portal could retain a shared deployment.

If an independent reporting team later emerges with its own release requirements, the decision can be revisited. The architecture then develops around a demonstrated need.

Record the decision on one page

Before a substantial split, I would write down five things:

  • Problem: What does not work well enough today?
  • Objective: How will we recognize improvement, such as less time waiting for a release?
  • Alternative: What smaller change might solve the same problem?
  • Cost: What additional development, operations, and failure-handling work will result?
  • Review date: When will we reassess the decision?

A modular monolith requires discipline. Microservices require it too, alongside the demands of distributed systems. I find extraction convincing when its concrete benefits justify the additional responsibility. The number of services is not a measure of success.

Facing this decision?

I help companies modernize their .NET applications and make architecture decisions that fit their teams and operations. If you are weighing up restructuring, splitting, and continued development, we can discuss your starting point in a free introductory call.

Get new posts by email

One mail per article. No newsletter theatre, no tracking pixels.

Unsubscribe with one click. Never shared.