Software Engineering & Data22 de março de 2024· Leitura: 3 min

Modular Monoliths vs. Microservices: The Pragmatic Architecture of MSC Company

Why MSC Company chose the modular monolith in Bun monorepos over microservices: no network overhead and single ACID transactions.

Modular Monoliths vs. Microservices: The Pragmatic Architecture of MSC Company

The Allure and Disaster of Premature Microservices

Between 2018 and 2023, the global software industry was swept by the dogma that any serious software company needed to adopt microservices from day one. Inspired by tech giants operating with thousands of engineers, mid-sized teams aggressively split unified codebases into dozens of isolated repositories and containers.

In the vast majority of cases, this resulted in the dreaded Distributed Monolith:

  • Compounded Network Latency: A user action that previously executed in memory in under 2ms suddenly triggered 8 internal HTTP/gRPC hops, elevating p99 latency beyond 350ms.
  • The Death of ACID Transactions: Atomic business operations (e.g., deducting an account balance and reserving inventory) required complex distributed sagas, leading to synchronization bugs and orphan database states.
  • Crippling DevOps Overhead: Teams spent more time managing Kubernetes clusters, service meshes, and fragmented CI/CD pipelines than delivering actual customer value.

At MSC Company, guided by our engineering constitution, we follow a pragmatic principle: Modular Monoliths by Domain.


What is a Modular Monolith?

A Modular Monolith combines the deployment simplicity and operational clarity of a monolith with the strict domain encapsulation of microservices.

The entire platform lives within a single, unified Bun monorepo, deploys as a cohesive Docker container on dedicated VPS infrastructure, and enforces rigid internal boundaries via Domain-Driven Design (DDD):

+-----------------------------------------------------------------------------------+
|                        MSC MODULAR MONOLITH ARCHITECTURE                          |
|                                                                                   |
|  [ Ingress Gateway (Elysia on Bun) ]                                              |
|                     |                                                             |
|                     v (In-Memory Function Calls - 0ms Network Latency)            |
|  +-----------------------------------------------------------------------------+  |
|  | UNIFIED MONOREPO CONTAINER                                                  |  |
|  |                                                                             |  |
|  |  +-----------------------+  +------------------------+  +----------------+  |  |
|  |  | Domain: Sales & Chat  |  | Domain: Billing & Sub  |  | Domain: AI Core|  |  |
|  |  | - WhatsApp Webhooks   |  | - Stripe Checkout      |  | - Prometheus   |  |  |
|  |  | - Lead Qualification  |  | - Invoicing & Tax      |  | - RAG / Vector |  |  |
|  |  +-----------------------+  +------------------------+  +----------------+  |  |
|  |              \                          |                         /         |  |
|  |               v                         v                        v          |  |
|  |  +-----------------------------------------------------------------------+  |  |
|  |  | Unified Persistence: PostgreSQL 16 + Drizzle ORM                      |  |  |
|  |  | (Single ACID transactions across domains with zero sync latency)       |  |  |
|  |  +-----------------------------------------------------------------------+  |  |
|  +-----------------------------------------------------------------------------+  |
+-----------------------------------------------------------------------------------+

Four Concrete Production Advantages

1. In-Memory Function Calls with Zero Network Latency

When the WhatsApp Sales Module needs to query pricing logic or check contract terms, it calls a typed TypeScript function in memory. There is no JSON serialization, no TLS handshake, and no risk of network timeout. Execution occurs in microseconds.

2. True ACID Transactions via Drizzle ORM

When an event booking requires creating a lead, locking calendar availability, and generating an invoice, everything executes inside a single PostgreSQL 16 transaction:

await db.transaction(async (tx) => {
  const lead = await salesModule.createLead(tx, leadData);
  await calendarModule.reserveDate(tx, lead.id, eventDate);
  await billingModule.generateInvoice(tx, lead.id, totalAmount);
});
// If any step fails, the database automatically rolls back with zero corruption!

3. Instant Refactoring and Strict Type Safety

Because all domains share the same TypeScript compiler, renaming a database field or refactoring an interface immediately updates all callsites across the entire codebase at compile time.

4. Single-Command Deployments

A single CI/CD build compiles and deploys the entire stack in under 30 seconds, eliminating cross-service version mismatches.


When Should a Module be Extracted into a Separate Service?

At MSC Company, we only extract a module into an independent service when justified by strict hardware and compute constraints:

Extraction TriggerArchitectural DecisionReal Example at MSC
Specialized Hardware (GPU)🟢 Extract to dedicated containerWhisper speech-to-text nodes running on NVIDIA GPUs
Asymmetrical Background CPU Spikes🟢 Extract to async workerMassive document ingestion and batch PDF processing
"To organize the code better"🔴 NEVER extractKeep encapsulated inside the Modular Monolith

Frequently Asked Questions (FAQ AEO)

Won't a modular monolith become spaghetti code over time?

No, as long as your team enforces strict module boundary linting. In our architecture, domains only interact through public service APIs exported in index.ts, strictly prohibiting direct internal imports or raw database cross-queries.

How does a modular monolith scale under high traffic?

Horizontal scaling is straightforward: deploy multiple identical stateless Docker containers behind a Traefik v3 reverse proxy. Load balancing distributes traffic across all containers without operational friction.


Related Articles & Next Steps:

Engineering Radar & Technical Inquiries

Scale your operations with audited AI and backend architecture

Subscribe to our technical briefing or submit your system requirements directly to MSC Company's lead architects. Responses within 1 business day.

Applied Engineering & AI

Scale Your Operations with Custom AI Systems

From autonomous WhatsApp agents to sovereign data architecture and fine-tuned SLMs. Talk directly to the MSC Company engineering team.

Contact MSC →
Related Articles

Continue Reading

View all articles →