Published Aug 16, 2026

Why we ripped out our microservices and went back to a modular monolith

By Kevin Champlin

Why we ripped out our microservices and went back to a modular monolith

The 3 AM pager alert that killed our distributed architecture

It was 3:14 AM on a Tuesday when the PagerDuty alert went off. Not a soft warning, but the kind of screech that makes your stomach drop. BridgeCare OS—our platform managing home-care agencies, shift scheduling, and state-mandated visit verifications—had gone dark on a critical authorization endpoint. A patient's electronic visit verification (EVV) payload had been accepted by the scheduling service, dropped by an SQS queue due to an unexpected null property in the JSON schema, but marked as completed in the billing ledger because an asynchronous event handler assumed success before the write confirmed.

Regulatory compliance does not care about your eventual consistency models. When an auditor asks for a definitive, immutable audit trail of who authorized a nurse's shift change, pointing to a distributed saga pattern involving fifteen different microservices, four message queues, and a distributed tracing tool that is currently timing out is a career-limiting move.

That night, sitting in the dark staring at Grafana dashboards, I made the call: we were killing the microservices architecture and pulling everything back into a single, aggressively structured Laravel modular monolith. The distributed systems tax was bleeding our engineering velocity dry, and nobody talks about the actual operational overhead of maintaining service boundaries when your domain model is inherently relational.

The hidden math of the distributed systems tax

Engineering teams adopt microservices because they read about Netflix or Spotify. They want independent deployments and team isolation. But unless you have fifty autonomous product teams shipping code around the clock, microservices are mostly an exercise in self-inflicted pain. For us, running fifteen separate Laravel and Node microservices meant:

  • Duplicating domain logic across service boundaries, leading to subtle drift in how caregiver permissions were evaluated.
  • Debugging cross-network race conditions where API gateways timed out before database transactions finished rolling back.
  • Wasting 40% of our sprint cycles simply updating API client SDKs, handling contract tests, and managing container orchestration configs.
  • Writing complex distributed locking mechanisms using Redis just to ensure two services didn't write conflicting state to the same patient record simultaneously.

When you are building software where a missed database constraint can lead to healthcare fraud allegations or lost state operating licenses, network boundaries are a liability, not an asset.

How we structured the modular monolith

Going back to a monolith doesn't mean writing a giant, unstructured ball of spaghetti in a single app/Http/Controllers directory. We kept the organizational clarity of microservices without the network tax by strictly enforcing domain boundaries inside a single Laravel 11 application using internal packages and explicit service providers.

Our directory structure now looks like this:

app/
  Modules/
    Scheduling/
      Actions/
      Contracts/
      Models/
      Providers/
      SchedulingServiceProvider.php
    Billing/
      Actions/
      Contracts/
      Models/
      Providers/
      BillingServiceProvider.php
    Compliance/
      Actions/
      Contracts/
      Models/
      Providers/
      ComplianceServiceProvider.php

Each module owns its database tables, its Eloquent models, and its public API contracts. A module can only talk to another module through explicit PHP interfaces registered in its service provider. If the Scheduling module wants to trigger a billing calculation, it injects a BillingManagerContract. There are no HTTP requests over internal Docker networks, no JSON serialization overhead, and—most importantly—database transactions span the entire operation natively.

If something fails, the entire transaction rolls back. No orphaned records, no dangling queue jobs, no phantom invoices.

The performance and velocity payoff

The results after consolidating back into a modular monolith were immediate and measurable across every metric that matters:

  • Deployment time: Dropped from a convoluted 22-minute Kubernetes pipeline across fifteen repositories to a pristine 90-second Forge deployment.
  • Error rate: Inter-service communication errors fell to absolute zero because network calls were replaced by direct method invocations.
  • Audit compliance: Generating a complete, cryptographically verified audit trail for a state compliance review went from taking three engineers half a day of log aggregation to running a single SQL join query that executes in 14 milliseconds.
  • Engineering velocity: Feature delivery speed increased by nearly 3x because developers no longer had to context-switch across multiple repositories and deployment pipelines just to add a new field to a patient intake form.

We applied the exact same architectural discipline to our other internal platforms—whether it's managing multi-model equities data in Vantage AI or handling high-throughput auto dealership reconditioning workflows in Auto Recon Manager. Clean boundaries beat network boundaries every single time.

Complexity should only be introduced when organisational scale demands it, never as an aesthetic choice for an early-stage product.

If your team spends more time debugging network timeouts and eventual consistency edge cases than shipping business logic, your architecture is solving problems you don't actually have.

When building complex platforms that require absolute data integrity and strict regulatory compliance, getting the architecture right from day one is critical. Learn more about how we approach systems design at Champlin Enterprises.

Free Tool

See exactly what AI costs — across every provider.

MyTokenTracker is a free, multi-provider intelligence platform with live pricing across 100+ models. Compare Claude, GPT-4o, Gemini, and more side-by-side — built for developers evaluating models, teams tracking API spend, and founders building AI-native products who want to stay cost-aware before it becomes a line item worth explaining.