Architecture · 11 min read · 2026-05-09

Modular monolith vs microservices: a decision matrix.

TL;DR — Microservices are a tool for a small set of real problems, not a destination. Eight specific signals justify the split. If a team can't tick at least four, the right answer is a well-bounded modular monolith. The Inara engagement that collapsed 40 services into 1 didn't fail microservices — it failed the question "did you need them in the first place?"

Why I keep getting this question

Three or four times a year I get a call that opens roughly the same way. "We're planning a microservices migration. Can you review the design?" By the time we're on a video call, the architecture diagram already has 18 to 30 boxes and a service mesh in the middle.

About half the time I push back hard. The other half, the team has already paid for it — they're calling me 18 months in because the AWS bill is climbing, deploys are slower than the monolith they replaced, and feature delivery has become a coordination problem with a side of code.

What's missing in nearly every one of those conversations is a clear test for whether the split is justified at all. Below is the test I run. Eight questions. If you can't answer "yes, with evidence" to at least four of them, you're shopping for a problem to solve.

The 8 questions

1. Do you have an actual independent scale profile, somewhere?

Microservices were originally Netflix's answer to the fact that their video-encoding pipeline scaled differently than their recommendation engine, which scaled differently than billing. If your services all scale with overall traffic — same shape of curve, same peaks — you don't have an independent scale profile. You have one workload pretending to be many.

Evidence test: graph requests-per-second per service over the last 90 days. If three or four services don't peak on different days or different times of day from the rest, you've over-fragmented your load.

2. Do you have multiple teams that genuinely need release autonomy?

Conway's Law is real — your architecture is going to mirror your org chart whether you want it to or not. But "two teams" doesn't mean "two services". The threshold I use: can each team deploy independently without breaking the others, with the org structure to support that. That requires CI/CD per service, contract tests, an API ownership rota, on-call separation. Most teams I see split services first and discover later they didn't have any of that infrastructure.

Evidence test: if any team has to ask another team for a deploy slot, or wait on someone else's release train, you don't have release autonomy. You have a monolith with extra YAML.

3. Is there a security boundary that has to be enforced at the network layer?

This one is real. PHI in healthcare. Cardholder data under PCI-DSS. PII under GDPR. If a regulator will read your network diagram and ask "show me how this database is isolated", a separate service with its own VPC, its own IAM role, and its own encryption envelope is the right answer. That's not microservices for fashion — that's microservices for compliance.

Evidence test: can you name the regulation, the auditor's question, and the specific control that the network split satisfies? If yes, keep that service split. The rest is open for negotiation.

4. Is there genuine stack heterogeneity that's load-bearing?

I've seen platforms where 38 of 40 services were Python and 2 were Go because someone read a blog post about Go's concurrency. In nearly every case, the Go services could have been Python and the team could have been one stack lighter on hiring, on observability tooling, on every dependency-update PR. The exception is when one workload genuinely needs a different runtime — a video encoder, a low-latency matching engine, a numerical library not available in your main stack.

Evidence test: for every non-default-stack service, name the specific runtime characteristic (latency, throughput, library) that the main stack can't deliver. "It's faster" doesn't count. "Its p99 latency is 8x lower under our load profile" does.

5. Can your testing infrastructure actually validate a distributed system?

A monolith you can test with one process, one fixture set, one assertion library. Microservices need contract tests, end-to-end tests on a representative environment, chaos testing for the failure modes the network introduces. If your team's answer to "how do we test this" is "we deploy and watch", you're not ready.

Evidence test: can a single developer reproduce a multi-service failure on their laptop in under 10 minutes? If not, the testing investment hasn't been made.

6. Do you have observability before you have services?

Microservices generate a roughly 6–10x increase in log volume and a similar multiple in traces. Without distributed tracing, structured logging with a correlation id, and alerting tied to actual SLOs, debugging a microservices outage is detective work with no clues. Teams that split before they had observability become teams that can't troubleshoot.

Evidence test: pick a recent production incident. Can you trace the request path through the system in under 5 minutes from the alert? If no, observability hasn't shipped.

7. Can you afford the cost floor — and do you know what it is?

Every service has fixed cost: a load balancer slice, a couple of pods for HA, a log stream, a deployment pipeline, a metric publisher. None of those scale with traffic — they're paid whether the service is busy or idle. For a 40-service stack on EKS, the floor I've seen is in the $1,500–3,000/month range before you handle a single user request.

Evidence test: compute your zero-traffic monthly bill. If that floor is more than 30% of your total spend, the architecture is paying its own salary instead of yours.

8. Is the modular monolith genuinely insufficient?

This is the question nobody asks. A modular monolith — single deployable, hard internal module boundaries, shared database with table-per-module discipline, in-process communication — handles most workloads up to several million users without breaking a sweat. It deploys in one go. It traces with one process. It tests in one suite. It costs a fraction of a microservices stack to run.

Evidence test: name the specific request that a modular monolith can't serve at your traffic volume. If you can't, that's your answer.

How to score it

Tally your "yes, with evidence" answers across the 8 questions:

0–1 yes  → Build a modular monolith. Period.
2–3 yes  → Modular monolith with one or two carefully chosen
           services extracted (the workload that genuinely needs
           independent scale or a regulatory boundary).
4–5 yes  → A small set of services (3–6) plus a core. Don't go
           further until the next yes appears.
6+ yes   → Microservices are the right answer. Invest in
           tooling and tracing first; cut services second.

Most teams I review come in scoring 1–2 and have built for 6+. That gap is what's eating their budget.

What a modular monolith actually looks like

The pattern that has worked best for me, including in the Inara collapse:

When the day comes that you genuinely need to extract a service — because question 1, 3, or 4 above turns true — the module boundary becomes the service boundary. Strangler-pattern extraction from a well-bounded modular monolith is straightforward. From a tangled monolith, it's a rewrite.

The Inara case in this frame

Inara had 40 services serving roughly 5,000 real users. Run the questions:

Score: 0–1. Result after the collapse: $3.5–5.5K/mo to $340–545/mo, deployment from half a day to ~15 minutes, team-to-run from 4–8 to 1–2. Same product, same uptime SLO. Full numbers in the Inara case study.

When this advice doesn't apply

If you scored 6 or higher with real evidence, this post isn't for you — your job is to invest in the tooling that makes microservices not-painful (tracing, contract tests, internal developer platform) before you cut more services. Skipping that step is the actual mistake.

If you're at a high-volume consumer platform — millions of daily actives, multiple specialised workloads, a platform team supporting product teams — microservices may be the only architecture that gets out of your way. Just be honest that you're in that population, and that most of the world isn't.


Wondering whether your platform is in the 0–1 group or the 6+ group?