Back to blog
Software Architecture5 min read

The Modular Monolith Is Back, and AI Is Why

The modular monolith is back, and this time it's not nostalgia. AI agents can't safely reason across ten services the way they can reason inside one.

Gabriel Santos

The Modular Monolith Is Back, and AI Is Why

"Start with a monolith" has been good advice for years for boring, human reasons: fewer moving parts, easier debugging, lower cost before you have traffic to justify splitting anything. In 2026 a second reason showed up, and it has nothing to do with humans at all.

The new failure mode

AI coding agents are genuinely good at reasoning about one codebase with clear module boundaries. They are much worse at safely reasoning across ten services glued together by network calls, each with its own deploy cycle, its own copy of a shared type, its own way of falling over. Ask an agent to make a change spanning three microservices and you are trusting it to model contracts it cannot fully see in one context window. Ask it to refactor a well-bounded module inside a monolith, and it is working on a problem sized for what it can actually verify.

Why this changes the calculus

  • A monolith with clear module boundaries gives an agent one process to reason about, not a distributed system to infer
  • Refactoring across a network boundary is riskier for an agent than refactoring across a function boundary, for the same reason it's riskier for a human, just more so
  • Teams report AI-assisted throughput rising while architectural drift, small inconsistencies compounding unnoticed, gets harder to catch specifically in distributed systems

None of this means microservices are wrong. It means the case for splitting a service now has to clear a higher bar: does the operational or scaling win actually outweigh the cost of making every future change, yours or an agent's, harder to verify safely?

What this looks like in practice

Keep the monolith, but keep it modular. Enforce real boundaries between modules, no reaching into another module's internals, no shared mutable state, so "modular" is an actual constraint your linter or architecture tests catch, not just a folder name. Extract a service when you have a concrete, measured reason: an independent scaling need, a genuinely separate team, a hard compliance line, not because splitting felt like the grown-up move. Simplicity used to be an ergonomics argument for humans. Now it is also a safety property for the tools writing code next to you. If your architecture only made sense with a human reviewing every line, what happens the day it does not?

Enjoyed this?

Explore more engineering articles from CodaCrew.