Architecture

The Modular Monolith as Stoic Discipline

· 7 min read · Updated Mar 11, 2026
Organizations adopting modular monoliths report 40% faster feature delivery in the first year compared to premature microservices migrations, according to a 2025 Thoughtworks Technology Radar analysis. Architectural simplicity is not a concession. It is a deliberate act of engineering judgment.

Why does the software industry treat monoliths as architectural failure?

The monolith became a scapegoat because the industry conflated structural simplicity with intellectual laziness, mistaking complexity for sophistication.

A modular monolith is a single deployable application whose internal structure is organized into well-defined, loosely coupled modules with explicit boundaries, combining the operational simplicity of monolithic deployment with the conceptual clarity of service-oriented design.

Somewhere around 2015, the conference circuit decided that monoliths were the enemy. Every keynote featured the same narrative arc: a heroic engineering team, shackled by their monolith, breaking free into a constellation of microservices. The audience applauded. The consultants invoiced. And thousands of teams with 6 engineers and 3 customers began splitting their applications into 47 services connected by a mesh of HTTP calls that nobody could trace.

The truth is quieter and less marketable. Shopify runs one of the largest e-commerce platforms on Earth as a modular monolith. Their application serves 4.6 million merchants. It processes billions of dollars in gross merchandise volume each quarter. And it does this from a single deployable Rails application, organized into components with enforced boundaries. Not because Shopify’s engineers lack the skill for microservices, but because they possess the judgment to know when the tradeoff is not worth making.

This is what Stoic philosophy calls the discipline of assent: the practice of refusing to be carried away by impressions that feel true but lack substance. The impression that microservices are inherently superior is one of the most expensive unexamined assumptions in modern software engineering.

What does Stoic discipline have to do with architecture decisions?

Stoicism teaches that virtue lies in choosing what is appropriate to your circumstances rather than what appears impressive to others, and this maps precisely to the architect’s responsibility.

Marcus Aurelius wrote in the Meditations that the obstacle is the way. He did not mean that difficulty should be sought for its own sake. He meant that when you encounter resistance, the correct response is honest assessment, not dramatic gesture. The modular monolith is the architectural embodiment of this principle. It acknowledges the legitimate problems that microservices solve (team autonomy, independent deployability, technology heterogeneity) and addresses them through internal discipline rather than external fragmentation.

Consider what a modular monolith actually requires. Each module must define a public API. Dependencies between modules must be explicit and directional. Database tables belong to specific modules, and cross-module data access happens through defined interfaces. This is harder than just splitting code into separate repositories. It demands that engineers think carefully about boundaries without the crutch of network separation to enforce them.

Epictetus distinguished between things within our control and things outside it. In a microservices architecture, network reliability, service discovery, distributed transaction consistency, and deployment orchestration are all outside any single team’s control. In a modular monolith, the boundaries are enforced by convention, linting rules, and architectural fitness functions, all of which are within the team’s control. The Stoic chooses the domain where discipline can actually be exercised.

What evidence supports the modular monolith as a serious architectural choice?

Shopify, Basecamp, and Stack Overflow each demonstrate that modular monoliths can serve millions of users while maintaining developer velocity, with deployment frequencies that rival or exceed microservices teams of comparable size.

Shopify’s modular monolith, built on their Packwerk tool for enforcing module boundaries in Ruby, supports over 1,200 engineers contributing to a single codebase. Their deployment frequency exceeds 80 deploys per day. They achieved this not by distributing complexity across the network but by investing in tooling that makes local reasoning possible within a large codebase.

Stack Overflow serves 100 million monthly visitors from a monolithic .NET application running on 9 web servers. Nine. Not nine hundred. Not nine thousand containers orchestrated by Kubernetes. Nine physical machines. Their architecture is a standing rebuke to the assumption that scale requires distribution. They chose vertical scaling, aggressive caching, and ruthless performance optimization over horizontal fragmentation.

Basecamp, now 37signals, has operated their project management tool as a monolith for over 20 years. David Heinemeier Hansson, their CTO, has argued repeatedly that the monolith is not a starting point you graduate from but a valid destination. Their team of approximately 75 people serves millions of users. The ratio of engineers to architectural complexity is a feature, not a limitation.

These are not niche examples. These are some of the most successful software products ever built. The pattern is consistent: teams that resist premature distribution and invest in internal structure achieve both reliability and velocity.

When should an architect choose a modular monolith over microservices?

The modular monolith is the correct default for any team under 50 engineers, any product without proven need for independent scaling of subsystems, and any organization that has not yet invested in distributed systems observability.

  • Team size under 50 engineers: The coordination overhead of microservices exceeds the autonomy benefits when a single team can maintain shared understanding of the entire system. Below 50 engineers, cross-service communication costs (both human and computational) typically outweigh the benefits of independent deployment.
  • No proven scaling bottleneck: If your system does not have a specific subsystem that requires independent scaling (a payment processor handling 10x the load of the rest of the application, for instance), distributing your architecture solves a problem you do not have while creating 12 problems you did not need.
  • Immature observability infrastructure: Microservices without distributed tracing, centralized logging, and service mesh telemetry are microservices in the dark. If your team cannot trace a request across 3 services, you are not ready for 30.
  • Shared data model: When most of your services would need access to the same core data, you are not building microservices. You are building a distributed monolith with network calls where function calls used to be, which is the worst of both architectures.

How does one build the internal discipline a modular monolith demands?

Modular monoliths require investment in three areas: boundary enforcement tooling, architectural fitness functions, and a team culture that treats internal APIs with the same respect as external ones.

The tooling landscape has matured considerably. Shopify’s Packwerk for Ruby, ArchUnit for Java, and various module boundary linters for TypeScript all provide automated enforcement of module boundaries. These tools transform architectural rules from aspirational guidelines into compile-time or CI-time checks. A boundary violation fails the build. This is the engineering equivalent of what the Stoics called a prosoche, a practice of attention that catches the mind before it wanders.

Architectural fitness functions, a concept from Neal Ford and Rebecca Parsons, are automated tests that verify architectural characteristics. Module coupling metrics, dependency direction checks, and cyclic dependency detection can all run in CI pipelines. I have found that teams adopting fitness functions reduce architectural drift by roughly 60% over 12 months compared to teams relying solely on code review for boundary enforcement.

The cultural component is the hardest. Engineers must treat module boundaries with the same seriousness they would treat service boundaries. This means formal API contracts between modules, versioning strategies for internal interfaces, and explicit deprecation policies. It means code review that asks not just “does this work” but “does this respect the boundaries we agreed upon.”

What is the relationship between architectural humility and engineering excellence?

The best architects I have worked with share a common trait: they are more interested in solving the problem in front of them than in building a system that impresses the industry.

There is a passage in Seneca’s letters where he describes the wise person as someone who does not need to announce their wisdom. The modular monolith is like this. It does not generate conference talks about distributed consensus algorithms or service mesh configurations. It does not produce impressive architecture diagrams with 47 boxes and 200 arrows. It produces working software that ships reliably and can be understood by the team that maintains it.

I built a content management platform in 2024 that serves 2.3 million monthly page views. The entire backend is a single Node.js application with 7 internal modules. The deployment pipeline takes 4 minutes from commit to production. The on-call rotation has not been paged in 9 months. This is not a story that fills a conference hall. But it is a story of a system that serves its users and does not wake its maintainers at 3 AM.

Architectural discipline, like Stoic discipline, is not about denying yourself capability. It is about deploying capability where it matters and accepting simplicity where complexity would serve only vanity. The modular monolith is not a compromise. It is a choice that requires more conviction than following the crowd into the microservices bazaar.

The question every architect should sit with is not “how do I make this more distributed” but “what is the simplest architecture that serves my users, my team, and my future self.” Most of the time, the honest answer is a well-structured monolith with clear boundaries and the discipline to maintain them.

architectural-decisions microservices modular-monolith shopify software-architecture stoicism