Why we still bet on .NET monoliths in the agent era — and out-ship the 30-person microservices team
AI agents amplify whole-program reasoning, and only a monolith gives them a whole program. The engineering case for the unfashionable architecture.
We are a five-person agency, we build modular monoliths, and we do it on purpose. That was a defensible-but-unfashionable position in 2022. In 2026 — the year every team acquired AI coding agents — it has quietly become an unfair advantage, and this post is the argument for why: agents amplify whole-program reasoning, and only a monolith gives them a whole program.
DHH planted this kind of flag about leaving the cloud; Plausible planted one about Google Analytics. Ours is smaller and more technical, but it is the same genre: the industry default is an architecture most teams adopted for reasons that do not apply to them, and the cost of the default went up just as everyone stopped looking at it.
The argument in one paragraph
Every guardrail that makes AI-generated code trustworthy — compiler verification, whole-solution reference finding, one build verdict per change, one architectural inventory — works best, and sometimes only, when the entire system lives in one compilation. Roslyn’s semantic model can answer “who calls this, what breaks if I change it?” across a modular monolith completely and mechanically. Split that system into twelve services and the same question crosses repo boundaries, serialized contracts, and version skew — territory where no compiler has jurisdiction and every agent is back to guessing. Microservices were a trade: coordination overhead in exchange for organizational independence. Agents just repriced that trade, because they made the thing monoliths are best at — whole-program change — dramatically cheaper, while doing almost nothing for the thing microservices are worst at: reasoning across network boundaries.
What the agent actually sees
Consider the change every architecture eventually faces: a field on a core concept — say, adding a TaxRegion to money handling — that touches persistence, business rules, API contracts, and UI.
In the monolith, our agent’s Roslyn MCP server returns every reference to the type in one call, compiler-verified, file and line. The planning pass holds the whole blast radius at once — modern frontier models take a million tokens of context, which comfortably fits the architectural map of a serious modular monolith. The change executes under one build gate: every affected call site either compiles or fails now, in this session, with the agent holding full context. One PR, one inventory diff showing exactly what moved.
In the microservices version, the same change is a distributed campaign: three repos, two shared contract packages, a consumer that deserializes the old shape until its team upgrades, and an integration environment where the truth eventually emerges at runtime. No compiler spans the boundary, so no investigation gate can verify claims across it; no single build verdict exists, so failures surface in staging, later, without context. The agent is not less capable there — it is less informed, structurally, and no prompt fixes structural blindness.
The uncomfortable arithmetic: agents made intra-process complexity cheap to navigate and did nothing for inter-process complexity. The architecture that minimizes network boundaries now compounds the productivity gain; the one that maximizes them dilutes it.
The numbers behind the flag
Our proof point is our own internal template: five connected applications — API, app frontend, admin, status page, docs — sharing one solution, one semantic model, one deploy story. Twenty-three production features, built by five people in six calendar weeks under the twelve-layer system. The infrastructure bill runs 94% below a comparable cloud-native scaffold — a single-region Aspire deployment, SQLite with Litestream where multi-tenancy doesn’t demand Postgres, boring choices the architecture permits precisely because it does not need a service mesh to have five things running. Compute on identical workloads runs 92% faster after NativeAOT and EF Core 10 upgrades that were safe to take because one compilation means one upgrade blast-radius, fully visible to the tooling.
“Five connected applications” is doing deliberate work in that sentence: modular monolith does not mean one process doing everything. It means the system compiles as one truth, deploys as one decision, and decomposes along module seams — seams that .NET Aspire lets you orchestrate locally and split later as a refactor rather than a rewrite, on the day a seam actually earns independence.
Against that, the 30-person microservices team from the title is not a straw man; it is a composite of teams we have been called into. Their velocity ceiling is rarely code — it is coordination: cross-team contract negotiation, versioned rollouts, the integration environment that is never quite production. Agents do not lift that ceiling, because that ceiling was never made of typing. A small team on a monolith spends its agent dividend on features; a large team on microservices spends much of theirs on the seams.
The objections, taken seriously
Monolith skepticism earned its place; here is how the standard objections fare under the agent-era math.
“Builds get slow at scale.” They do — and this matters more now, because our build gate runs between agent steps. The mitigations are unglamorous and effective: incremental compilation, project-scoped test filters (dotnet test --filter against only the projects a change touched), and treating build time as a first-class performance budget. Our five-application solution gates in seconds, not minutes, because we spend engineering effort keeping it there. A team unwilling to maintain that budget will feel the ceiling — that is a real cost of the bet, and we pay it knowingly.
“Monoliths rot into big balls of mud.” Unstructured monoliths rot. The modular discipline is enforceable, and — this is the part that changed — now enforceable mechanically: the dependency-graph tooling in our Roslyn MCP server makes a layering violation a queryable fact, the pattern snapshots keep generated code inside module conventions, and the agent itself is subject to both. The mud was never the architecture’s fault; it was the absence of enforcement — which is exactly what the guardrail stack supplies.
“Everyone steps on each other in one repo.” Vertical-slice structure gives each feature its own folder-shaped territory, and agents reduce contention further: the mechanical mid-sized changes that used to have three humans brushing shoulders in shared files are now executed serially, quickly, under gates. Five people, one repo, no meaningful merge pain — at thirty people this objection regains force, and appears in the honest list below.
“One deploy unit means one blast radius.” True, and the answer is speed plus flags: deploys fast enough to make rollback a non-event, feature flags to separate deploy from release. The alternative blast radius — a distributed rollout where service A’s new contract meets service B’s old deserializer — is not smaller; it is just harder to see.
Where microservices are still correct
A flag-plant that concedes nothing is marketing, so here is what we tell clients whose answer genuinely is microservices:
- Independent scaling of a genuinely hot path — when one component’s load profile is orders of magnitude different and the money depends on scaling it alone.
- Organizational scale — north of roughly thirty engineers in multiple autonomous teams, Conway’s law stops being a warning and starts being load-bearing. Microservices are an organizational technology; at that size the coordination cost exists either way, and boundaries make it explicit.
- Hard isolation requirements — regulatory or security boundaries where a process boundary is itself the control.
- Polyglot necessity — a component that truly must be Python or Rust for its ecosystem.
- Independent deploy cadences with teeth — when different parts of the system genuinely ship on incompatible rhythms with different risk appetites.
What we push back on is adopting the org-chart architecture of a company you are not, at five or ten engineers, for scale you do not have — and paying for it twice now: once in coordination, and once in forgone agent leverage.
The decomposition ledger
“Split it later” is only honest if you can say what later looks like, so we keep an explicit ledger of leading indicators — the signals that a module seam is earning its independence:
- Deploy-cadence divergence. A module that repeatedly needs shipping on a different rhythm than the rest — not once, repeatedly — is announcing a boundary.
- Sustained asymmetric load. When one module’s scaling pressure keeps forcing infrastructure decisions on modules that don’t share it, the bill for co-location has arrived.
- Ownership hardening. When a team stops touching a module they nominally share, and its review culture diverges, Conway’s law has already drawn the line — the architecture is just late to acknowledge it.
- The inventory says so. This is the agent-era addition: the dependency graph and AUTO-TABLE data show, empirically, which module boundaries are crossed least. When a seam has been effectively closed for two quarters — few cross-references, no shared-entity churn — it is a low-risk cut, and we know it from data rather than architecture-meeting vibes.
The point of the ledger is that decomposition becomes a decision with evidence instead of a rewrite born of frustration. Monolith-first was never monolith-forever; it is monolith-until-the-data-argues, which is a very different commitment.
The bet, restated
Architecture debates age badly because the constraints move. So state ours with its constraints attached: for small senior teams building product-shaped systems, the modular monolith is the highest-leverage architecture of the agent era — because it is the architecture the verification tooling can fully see. If the constraints change — the team triples, a seam earns independence — the monolith decomposes from a position of knowledge: the inventories already show where the real seams are.
The deeper treatment of the tooling that makes the bet pay is the twelve-layers hub and the field guide. And if you are mid-argument with your own team about this, that is exactly the kind of hour an $80 consult is for — we have made this call in both directions, and the direction matters less than making it for your constraints instead of someone else’s.
Related Posts
AI coding guardrails for regulated industries: what we ship for fintech, govtech and assurance clients
How the twelve-layer system maps to GDPR, DORA, NIS2, and SOC2 — with the audit artifacts each layer produces as a side effect of normal development.
How we run Claude Code on a 5-developer .NET team — with our actual CLAUDE.md, hooks, and skills
Our real production setup, published: the hook roster, five subagents with model tiers, eight MCP servers, and the machinery that makes agent output shippable.
What a .NET SaaS actually costs to build in 2026 (with the line items)
In-house, offshore, or AI-augmented boutique — real 2026 cost ranges for building a .NET SaaS, itemized down to the 23 features every product needs first.