Software Architecture

Monolith, Microservices or Modular Monolith?

Monolith, Microservices or Modular Monolith?

About this article

This article is the second deep dive in the “Software Architecture” category of the Architecture Crash Course for the Generative-AI Era series, covering how to choose an application’s overall structure.

“How many pieces, integrated or separated?” is the least reversible decision in software architecture. The article compares the three patterns (monolith / microservices / modular monolith) and shows the modern default: “start as modular monolith, carve out as needed.”

Before you read this

This article is mostly about development: programs and APIs. If IT vocabulary is unfamiliar, reading the primer "Programs and APIs" first makes it far easier to follow. You can also look anything up in the glossary as you read.

What is overall structure in the first place

Monolith → Modular Monolith → Microservices Gradual Migration

Overall structure is, in a nutshell, “the basic policy of how many pieces to split an application into and how they interact.”

Imagine running a restaurant. A small shop is most efficient with one owner doing all the cooking, serving, and checkout (monolith). For a chain, splitting cooking, serving, and checkout among specialists coordinated via manuals (microservices) scales better. In between, you can clearly divide the kitchen, floor, and register within one shop and prepare to spin them off if needed (modular monolith). Software is the same: you need to pick the right division method for your scale and operational capacity from the start.

Why choosing overall structure matters

What happens if you proceed without thinking deeply about overall structure? Trying to split a single app into multiple later means rewriting at scale — practically close to a rebuild. Conversely, consolidating multiple separate apps into one is heavy work involving data migration and downtime.

Overall structure is the precondition for every other technical choice. Leaving it vague forces redoing every downstream decision: framework, language, headcount, cloud, test strategy, deployment — all depend on it. For a single app vs functions split into integrated services, the engineer count and skill mix differ by an order of magnitude. What 5 people build as the former might need 20 as the latter.

“Build now, split later” is theoretically possible but essentially a rebuild in practice. Underestimating it hurts.

Trying to split a single app into multiple later means rewriting at scale — practically close to a rebuild. Conversely, consolidating multiple separate apps into one is heavy work involving data migration and downtime. Decide deliberately at requirements time, with future scale and operational capacity in mind.

Overall structure is the precondition for every other technical choice. Leaving it vague forces redoing every downstream decision: framework, language, headcount, cloud, test strategy, deployment — all depend on it.

For a single app vs functions split into integrated services, the engineer count and skill mix differ by an order of magnitude. What 5 people build as the former might need 20 as the latter.

“Build now, split later” is theoretically possible but essentially a rebuild in practice. Underestimating it hurts.

The three basic patterns

The Three Application Structures Run a restaurant, and the relation between scale and staffing is easy to see Monolith The owner does everything Cooking Service Till → all by one Upsides Overwhelmingly fast to start Easy to keep data consistent Simple to run and monitor Downsides Development slows once it grows One failure stops everything Small to mid (1–10 people) The only choice for an MVP Microservices A chain, with specialists Cook Serve Till Deliver Upsides Good at parallel development Failures can be localised Scales part by part Downsides Operating cost of another order Hard to find the cause Large (30+, many teams) Copied by a small team, it collapses Modular monolith Pick One store, divided into areas Kitchen Floor Till Upsides Runs about as easily as a monolith Easy to split later Few conflicts even with many people Watch out for Needs discipline to hold the boundaries Slightly harder to design Mid-size (10–30 people) Where to land when in doubt The 2010s praised microservices; the 2020s are returning to the modular monolith

The application’s overall structure splits into three: monolith, microservices, modular monolith.

PatternQuick description
MonolithTraditional: all features in one app. Simplest
MicroservicesEach capability as an independent app, integrated over network
Modular MonolithLooks like one app, internally split with explicit boundaries

Microservices boomed in the 2010s; today there’s a swing back to modular monolith. The level-headed view now settling in: not new vs old — pick by scale and organization.

Monolith — still the best at small to mid scale

True to “Monolith,” the most traditional structure: all features in one application. Login, payment, inventory all run on the same code, server, DB. From e-commerce to enterprise systems, much of the world’s software is still built this way.

At small/mid scale, it’s overwhelmingly the fastest to start, easiest for data consistency, easiest to debug. But at huge scale, builds get long, multi-person changes collide, and one feature’s bug stops the whole app.

ProsCons
Overwhelmingly fast to startHeavier development at huge scale
Easier data consistencyMulti-person change collision
Easier debuggingOne feature’s outage stops the whole app
Simple operations / monitoringTech selection is unified across the whole

Examples: Ruby on Rails apps, Spring Boot enterprise systems, WordPress.

“Monolith = old” is a misreading. It remains the best choice at small / mid scale.

Microservices — a structure for parallel development in a large organisation

Microservices runs each capability as a small independent app, integrated over the network. For e-commerce, “User,” “Catalog,” “Payment,” “Shipping” become separate apps talking via APIs to form one product.

In the 2010s, Netflix and Amazon adopting it spread the model. You can split teams per capability and develop in parallel; you can scale parts. But operational complexity grows by orders of magnitude. As service count grows, just building monitoring, log aggregation, and distributed tracing becomes a project of its own.

ProsCons
Per-capability parallel team developmentWhole-system complexity skyrockets
Localize partial outagesOperational and monitoring cost explodes
Per-service tech choiceInter-service communication degrades performance
Scale parts independentlyBug-cause identification is hard

Examples: Amazon, Netflix, large-scale services.

Only viable with a large org and operational capacity. Small teams copying it almost always break.

Segment’s “Goodbye Microservices is the case everyone cites here.

The analytics platform Segment ran 140+ microservices from 2013, then in 2018 published “Goodbye Microservices and consolidated back into a monolith. Service-chain failures, deployment coordination, exploding test environments — solvable individually but together unmanageable. The story circulated widely.

That a company with that level of engineering couldn’t manage it carries weight. Many remember the “finally, someone said it” wry tone in the industry at peak microservices fervor. Worth remembering this case before jumping at microservices because “Netflix uses them.”

Distribution is multiplicative, not additive. Doubling services means quadrupling integration patterns.

Modular monolith — where to land when in doubt

Modular Monolith looks like a monolith (one app) but uses explicit internal boundaries. Internally split into “User,” “Catalog,” “Payment” modules — modules don’t call each other freely; they only integrate through defined interfaces.

One app, so deployment and operations stay monolith-simple, while internal structure is clean — making future microservices carve-out cheap. Aiming at the “monolith’s operational simplicity” plus “microservices’ clean structure.”

ProsCons
Operations as simple as monolithDiscipline required to enforce internal boundaries
Future split is comparatively easyWithout splitting, the value is thin
Less collision in large-team developmentSlightly higher design difficulty
One DB makes consistency easyLess parallelism than microservices

The modern default. When in doubt, start here, then carve out partial microservices as needed. That’s the default.

Modular monolith is “the when-in-doubt” default. Splitting is always available later.

The three compared

Software Structure Patterns Compared Aspect Monolith Modular monolith Micro- services Easy to start × Low operating cost × Parallel development at scale × Localising a failure × Easy to split later × People and skill needed Few Few to mid Many Learning cost Low Mid High

Lining up the three on key axes: monolith wins on “ease of start” and “ease of operations”; microservices wins on “parallel development” and “outage isolation.” Modular monolith sits in the middle with circle-or-better on most axes — a good balance.

AspectMonolithModular
Monolith
Micro
services
Easy to start×
Low ops cost×
Large-scale parallel dev×
Outage localization×
Future split ease×
Required staff/skillFewFew-midMany
Learning costLowMidHigh

Microservices does “more” but the cost paid is overwhelmingly larger — that’s the right framing.

How to choose — three scenarios by scale

The deciding factor is Conway’s law — the empirical rule that the structure of the organisation determines the structure of the system. Team size and operational capacity settle the candidates almost entirely.

The criteria that actually decide it are these.

1. Scale and team size. Team size is the largest factor. Adopting microservices with 1-10 people means not enough hands per service split; one person juggles multiple, and you only pay operational cost without the benefit.

Conversely, a 100+ person org maintaining a monolith means everyone touches the same codebase: change collisions, deploy contention, review delays. Splitting per capability lets teams work independently and raises overall productivity.

ScaleSuitable form
A few to 10 peopleMonolith overwhelmingly favorable
10-30Modular monolith is safe
30+, multi-siteConsider microservices

Conway’s Law (the empirical observation that org structure reflects in architecture) plays out heavily. One team with microservices: no split benefit, just increasing operational cost.

2. Can you operate it? Microservices operations is harder than imagined. Even one app needs monitoring, logs, deploys; with 10-20 services, dedicated platforms (distributed tracing, service mesh: shared infrastructure handling inter-service traffic) for cross-service monitoring and incident tracking become mandatory.

Operating these requires at minimum a few dedicated infra people experienced with containers and distributed systems. “Functions are independent and that feels good” is the developer view; from operations, managed objects grow exponentially.

  • Are there people who can build cross-service monitoring and logging?
  • Is there container / distributed-systems operational experience?
  • Is there capacity to chase bugs across multiple services?

If any of these is missing, don’t choose microservices. No exceptions.

3. Which growth phase you are in. Growth phase also shifts the optimal. At idea validation / MVP stage, releasing fast and gathering market signal is the priority.

Default to monolith — fastest to build. Starting straight in microservices means infrastructure consumes the time meant for features, and the canonical failure pattern is “collapse at MVP stage”.

After PMF (Product Market Fit) and into expansion, with growing team, organize into modular monolith. Once the org grows past one app’s manageability, carve out the bottlenecked features as microservices.

PhaseRecommended
Idea validation / MVPMonolith for fastest release
Post-PMF expansionModular monolith to organize structure
After org growsCarve out specific features as microservices

If it is a solo or startup MVP — monolith, no alternative

Speed of building comes first, and taking on operational complexity while you still do not know whether users will show up is suicidal. Starting straight into microservices is the classic failure: infrastructure work eats the time before any feature exists, and the project runs out of strength at the MVP stage. Aim for the fastest release with a framework one person can build all of — Rails, Laravel or Next.js.

Personal / Startup: Ship in One Month Is Correcten.senkohome.com/arch-intro-case-startup/

If it is a small or mid-size SaaS or internal system — draw boundaries with a modular monolith

In the expansion phase after product-market fit, with a team of ten to thirty, make the internal boundaries explicit with a modular monolith. When a split does become necessary later, it is dramatically cheaper than splitting a monolith that had no boundaries. The point is to keep consistency in one database while allowing modules to talk only through interfaces.

Small-Mid SaaS - Lean on Managed and Run with Few Peopleen.senkohome.com/arch-intro-case-saas/

If it is a large enterprise with parallel teams — microservices, with the ops investment

Only once you pass thirty people across multiple locations and genuinely want each team to deploy independently do the benefits of microservices exceed the cost. Even then, three things have to be in place: cross-service monitoring and log infrastructure, people with experience operating distributed systems, and a fault-tracing setup that works across services. If even one is missing, do not choose it — without exception.

Large-Enterprise Core: Design That Holds Up for Yearsen.senkohome.com/arch-intro-case-enterprise/

The same question, framed case by case, lands like this.

Solo, or a startup MVP. Monolith only. Build speed is the priority; carrying operational complexity at a stage when users may not even arrive is suicidal. Pick frameworks like Ruby on Rails, Laravel, Django that “one person can build it all” for fastest path.

Mid-sized business applications — internal systems, early SaaS. Modular monolith. With future feature growth expected, set internal boundaries from the start. When splitting becomes necessary, it’s overwhelmingly cheaper than splitting from a monolith.

Large-scale services with several teams developing in parallel. Microservices. Per-team independent deploy / release pays off; benefits scale with the org. Investment in operational platforms is mandatory.

An existing monolith where one feature has performance problems. Carve just that feature into microservices. No need to rebuild everything. “Want to scale just notifications” -> carve out notifications, keep the rest.

Future expansion uncertain, small today. Modular monolith. Going monolith first then splitting later is much costlier than starting modular and carving when needed.

A practical scale × structure ladder

Note: industry rates as of April 2026. Periodic refresh required.

Including Conway’s Law, team size effectively decides recommended structure:

Org phaseHeadcountRecommendedTypical service countDB
MVP / individual1-3Monolith11 DB
Early startup3-10Monolith → Modular monolith11 DB
Mid-sized SaaS10-30Modular monolith1-31-2 DBs
Scale30-100Modular + partial microservices5-15Per use
Enterprise / multi-site100+Microservices (core) + modular monolith (operational)30-hundredsPer service

The practical floor for microservices: “30+ team + 5+ dedicated ops.” Below that, inter-service traffic, distributed tracing, and data-consistency operational costs just balloon; dev speed drops.

Segment’s 2018 reorganization from 140 services back to a few symbolizes “out-of-scale microservices.”

Microservices is a 30+-person privilege. Copying it as a 10-person team almost certainly breaks.

Triggers for carving a service out of a modular monolith

When should pieces be microservice-extracted from a modular monolith? Don’t rely on vague “when it gets big” — use numerical thresholds.

Carve-out signalTarget
Dev team requests independence30+, multi-site
Specific feature receives 10x+ requests vs wholeWant to scale just the spike
Build time blocks development10+ minutes / deploy frequency drops
Specific feature’s SLO diverges sharplyPayment 99.99%, rest 99.9%
Want different language / runtime per partML inference Python, main TypeScript

Carve out by “the bottleneck or independence-needing area,” not by feature. Splitting everything at once almost always fails.

AI decision axes — Can the AI take in the whole codebase at once?

Once AI-driven development becomes the norm, “can AI survey the entire codebase” becomes an additional consideration for structure selection. Modular monolith is a structure that makes boundaries explicit within one codebase, making it easy for AI to grasp full context — earning reappraisal as the prime candidate for the AI era.

Microservices fragment AI’s context

Imagine 10 microservices. When you ask AI to “fix the order-processing bug,” if the order service, inventory service, and payment service code live in separate repos, AI can only view each independently. Inter-service message contracts and implicit dependencies often don’t appear in code, making it difficult for AI to produce fixes that maintain overall consistency.

With a modular monolith, AI can grasp the boundaries and dependencies of order, inventory, and payment modules all within one repository. Boundaries exist but context stays connected — this is the most productive structure for AI utilization.

Monorepo + type sharing combination

Even when adopting microservices, consolidating all services in a monorepo (Nx, Turborepo, etc.) and sharing type definitions dramatically improves AI utilization efficiency. With AI able to read the entire repository, it can detect type inconsistencies between services and API compatibility breaks.

Pitfalls and forbidden moves

Here are the six most dangerous of the traps that come up when deciding to split an existing monolith.

Forbidden moveWhy it is bad → what to do instead
Converting every feature to microservices at oncethe complexity of distribution grows exponentially → carving out one at a time (Strangler Fig) is the only realistic answer
Keeping a shared database through the splitthe tight coupling survives and the independence benefit disappears → separating the database is the real substance of a split
Building inter-service communication on synchronous REST aloneone service failing propagates to everything → combine it with asynchronous messaging (Kafka, SQS)
Adding distributed tracing and log aggregation afterwardscauses become unidentifiable during an incident and MTTR runs into hours → have them from day one of distribution
Implementing distributed transactions without knowing Saga or Outboxdouble payments and stock inconsistencies appear in production → learn the design patterns first
Choosing on the thought-terminating “microservices means modern”it is one option among several → choose calmly on scale, staffing and phase

Starting the order — modular monolith, then partial microservices — from around ten people is the standard path. Going back to a monolith is harder than building one, so the strongest defence is not running to distribution in the first selection.

What you must decide — what’s your project’s answer?

Articulate your project’s answer in 1-2 sentences for each:

  • Initial release form (monolith / modular / micro)
  • Internal module boundaries (by feature or by business domain)
  • Database split or shared
  • Future-split scenario set assumed
  • Operational capacity (monitoring / deploy / incident) holds for the configuration
  • Team org structure aligns with design (Conway’s Law)
  • First feature to carve out if microservicing

Write your answers down as an ADR. A concrete guide to writing them is here.

[DevOps Architecture] Documentationen.senkohome.com/arch-intro-devops-docs/

Summary

This article covered software architecture’s overall structure — three patterns of monolith / microservices / modular monolith from scale, operational capacity, and growth phase.

When in doubt, modular monolith. MVPs always monolith. Microservices floor: 30+ + 5+ dedicated ops. The 2026 realistic answer including AI era.

The next article covers module design (Layered / Hexagonal / Onion / Clean).

Back to series TOC -> ‘Architecture Crash Course for the Generative-AI Era’: How to Read This Book

I hope you’ll read the next article as well.