#.NET & Architecture

Does this really need microservices?

Zulu Shack illustration for “Does this really need microservices?”: one big pot, small linked pots

If a small business application is becoming difficult to change, splitting it into several applications can sound like a clean solution.

Sometimes it is. Sometimes we’ve taken an untidy kitchen, put each station in a different building and introduced a radio system. The organization has improved on paper. Getting a sandwich out now involves weather conditions.

A modular monolith offers another option: one deployed application with deliberately separated responsibilities inside it. Milan Jovanovic’s March 2024 explainer provides a timely reason to consider that approach before assuming separate services are the next stage of maturity.1

Let’s test the choice against a fictional booking system.

Draw one booking from request to confirmation

The system checks availability, records a booking, takes payment and sends a confirmation. Each responsibility needs a clear owner. That does not automatically mean each needs a separate deployment.

A useful architecture review follows the change and asks where information is read, where it is updated and what happens when a step fails.

Separate responsibilities without moving every conversation onto the network

A modular monolith might have booking, payment and notification modules with defined interfaces. The team can restrict how those modules interact while running the application as one unit.

That is different from a large codebase where everything reads and changes everything else. Putting folders around the confusion won’t create boundaries, although the file tree may look much more employable.

Define which module owns a rule and its data. Other parts of the application should use agreed interactions rather than quietly modifying another module’s internals.

Jimmy Bogard’s vertical-slice approach can help organize individual use cases within a suitable architecture.3 It addresses how related feature concerns are grouped; it isn’t a requirement to choose either a monolith or microservices.

The practical benefit is understanding what a change touches. A cancellation should have a traceable path, whichever deployment model you choose.

When off-the-shelf stops fitting, see how we approach custom development.

Ask what independent services would actually buy

Separate services can support independent deployment, distinct scaling needs and clearer ownership across teams. Those are meaningful advantages when the business and operating team need them.

They also introduce network calls, separate failure modes and more work around diagnosis, releases and data consistency. A payment service can be unavailable while the booking service is working normally. The overall customer journey still needs an answer.

For the fictional system, ask whether one responsibility genuinely needs a different release schedule or capacity profile. Also ask who will monitor it and resolve a partial failure.

If the answer is that everything still has to change and deploy together, the separation may be adding coordination without delivering much independence. That’s worth knowing before the radios arrive.

Modular monolithSeparate services
DeploymentOne application, released as a unitIndependent deployments for each service
BoundariesModules with defined interfaces inside one codebaseSeparate applications that talk over the network
What can go wrongDependencies creep across modules and make later extraction harderNetwork calls, partial failures and coupling through shared data or synchronised releases
A good fit whenA smaller team maintains one business applicationGenuinely independent teams need different release schedules or capacity
Modular monolith or separate services?

Look at the operating team, not just the diagram

Martin Fowler’s Monolith First discussion argues that service boundaries can be difficult to identify early and that managing distributed services carries a premium.2 It also acknowledges that the choice isn’t universal.

Check out this blog: Laravel or .NET? Start with the business, then have the argument.

I agree with the need to connect architecture to the team’s actual circumstances. A smaller team maintaining one business application may benefit from clear internal modules and a simpler deployment. A larger organization with genuinely independent teams may have stronger reasons for services.

Neither approach removes the need for discipline. A modular monolith can accumulate dependencies that make later extraction difficult. Microservices can become tightly coupled through shared data and synchronized releases.

Zulu Shack recommends choosing the simplest operating model that meets the demonstrated needs, while keeping business boundaries explicit. Extract a service when the benefit is concrete enough to justify running it.

For the booking system, that may mean building and improving one well-organized application first. Record the assumptions and revisit them when real usage, team structure or release constraints change.

You can have a thoughtful architecture without distributing it across the postcode. Sometimes the most useful boundary is the one the team can explain and maintain together.

Turn reading into results

Like what you’re reading? Let’s put it to work on your brand.