TLDR (Quick-Answer Box)
Microservices earn their cost only when team structure already maps to service boundaries, a specific scaling bottleneck is measured in production, and the CI/CD and observability foundation is already in place.
Build the monolith first. Extract services when a real bottleneck makes the trade-off clear - not in anticipation of scale that hasn’t arrived. The reversal stories from Amazon Prime Video and Twilio Segment both followed the same pattern: organizational mismatch drove architectural complexity, and consolidation fixed the underlying problem.
Summarize this post by:
In 2023, Amazon Prime Video cut infrastructure costs by 90% after rebuilding their video quality monitoring system as a single, unified service. The move reignited the monolith vs microservices debate.
Teams that adopted microservices without the organizational structure to support them paid for it. Services ended up deployed separately but tightly coupled, sharing databases and failing together when any component broke. Engineers spent most of their time managing infrastructure instead of shipping product. This failure mode is the distributed monolith, and it is more common than most engineering leaders expect.
This article is for your team to work through the monolith vs microservices decision. It covers how to identify the distributed monolith before it compounds, when microservices genuinely justify their cost, and a practical framework for making the call with the team you have today.
What does a monolith really mean?
A monolith is an application deployed as a single unit. The database layer, business logic, API layer, and user interface are all packaged and released together from one codebase.
There are two variants of the monolith. A traditional monolith has tightly coupled code where all components are interdependent and deployed together as one piece. A modular monolith has clearly defined internal module boundaries with separate domain logic per module, but still ships as a single deployment. The modular structure enforces separation without the operational overhead of running independent services.
A monolith is not inherently “legacy” architecture. As an architectural choice, it comes with real advantages:
- Simple deployment pipeline. All components ship as one unit, with no per-service CI/CD to configure or maintain.
- Low network overhead. Internal function calls replace network calls, eliminating serialization overhead, inter-service latency, and service mesh complexity.
- Centralized debugging. A single log stream and call stack make tracing issues straightforward.
- Full ACID transactions across the entire data model, with no need for distributed transaction patterns.
The failure mode of a monolith is not being a monolith. It is allowing the codebase to grow into an unmodularized ball of mud with no enforced domain boundaries, at which point changes in one area unpredictably break others. That is a discipline problem, not an architecture problem, and it is solvable without migrating to microservices.
💡 Running on a single server is not what makes something a monolith. Monolith describes deployment topology, not infrastructure. A monolith can run in Docker containers, behind a load balancer, or on Kubernetes and still be a monolith.
What microservices architecture really requires
A microservices architecture breaks an application into independently deployable services. Each owns a single business domain and communicates with other services via APIs or message queues. Unlike SOA, which shared services through a common enterprise bus with centralized orchestration, microservices require each service to own its data and release independently.
The defining characteristic is independent deployability. Each service can be built, tested, and shipped by a separate team without coordinating a full-application release. This is the core value proposition, and it is also the first thing that disappears in a poorly executed microservices adoption.
A functioning microservices system requires several architectural components working together.
- An API gateway routes requests from clients to the appropriate service and aggregates responses. It is the entry point for every external call.
- Service discovery lets services locate each other dynamically without hardcoded addresses, which matters in cloud environments where IPs change on every deploy.
- A circuit breaker isolates failing services so a single failure does not cascade across the system.
- A message queue (Kafka and RabbitMQ are common choices) enables asynchronous service-to-service communication for workflows where an immediate response is not required.
These four components reflect the design principles that separate a real microservices system from a distributed monolith in production.
Communication happens in two patterns. Synchronous communication via REST or gRPC handles real-time request-response interactions. Asynchronous communication via event streaming handles workflows where decoupling the producer from the consumer improves resilience.
Conway’s Law is the organizational principle that makes or breaks microservices. Organizations design systems that mirror their own communication structure. So, microservices architecture should follow team boundaries, not precede them. When the team structure is not already organized around independent domains, the architecture reflects that mismatch, usually as a distributed monolith.
A common mistake is building too many, too fine-grained services. Nanoservices multiply coordination overhead without proportional benefit and accelerate drift toward the distributed monolith pattern.
Monolith vs microservices: The real trade-offs
The trade-offs between these two architectures become clearest when compared directly across the dimensions that matter most to engineering leaders.
| Criteria | Monolith | Microservices | Serverless* |
| Codebase | Single, unified | Multiple, independent per service | Function-level |
| Deployment | Single unit, all-or-nothing release | Independent per service | Per function, on-demand |
| Scaling | Scale entire application vertically | Scale individual services horizontally | Auto-scales; pay per invocation |
| Debugging | Centralized logs, single call stack | Distributed, requires tracing tools (Jaeger, Zipkin) | Event-based; difficult to trace end-to-end |
| Operational overhead | Low | High: service mesh, orchestration, per-service CI/CD | Medium: cold starts, vendor lock-in |
| Best team fit | 1–15 engineers, shared codebase | 10+ engineers, separate teams per domain | Event-driven or infrequent workloads |
| Time to first deploy | Fast | Slow, significant infrastructure setup required | Fast |
*Serverless is included as a third-option reference for teams evaluating all three approaches. It works well for event-driven, infrequent workloads but introduces cold-start latency and pricing variability at sustained volume.
A few trade-offs deserve more than a table cell.
On scalability, horizontal scaling of microservices is only an advantage when individual services have meaningfully different scaling curves. If all services scale together under the same traffic patterns, a monolith scaled vertically is often cheaper and simpler.
On developer velocity, microservices improve velocity for teams that have already established clean domain boundaries and independent CI/CD pipelines. For teams still building those systems, microservices slow velocity significantly during setup and stabilization. The velocity return comes later, and only if the organizational structure supports it.
Operational overhead that is trivial for a 50-engineer organization can overwhelm a team of eight. Architecture decisions made in anticipation of future scale rather than current constraints underestimate that cost. The right architecture is not the one that looks best on a comparison table. It is the one that fits the organization as it exists today.
The distributed monolith trap: How most teams fall into it

Most teams do not actually get microservices. They get a distributed monolith. Services are deployed separately but remain tightly coupled, inheriting the complexity of a microservices architecture while retaining the fragility of a poorly structured monolith.
The coupling usually starts small. Two services share a database table because it seemed expedient. A third begins calling the first synchronously because the async alternative would take two extra sprints to implement. The architecture diagram says microservices. The production reality is a distributed monolith.
A system has crossed into distributed monolith territory when five diagnostic signals are present.
- Deploying one service regularly requires deploying two or more others at the same time.
- Multiple services share a database schema or access the same tables directly.
- A failure in one service causes cascading failures in services that should be independent.
- Adding a new feature requires changes across four or more services.
- Running a test for one service requires the full system to be running.
This pattern emerges when teams draw service boundaries along technical layers rather than business domains. Each “frontend service,” “API service,” and “data service” needs the others to function. The result looks like microservices on an architecture diagram. But it behaves like a coupled monolith in production, with the added overhead of network calls between tightly dependent components.
Conway’s Law provides a quick organizational diagnostic. If the teams that own different services share daily standups, sprint planning, and the same backlog, they are operationally one team. One team should have one service. The architecture tells the truth about the organization, even when the deployment topology says otherwise.
The distributed monolith is the most expensive architecture a team can accidentally build, because it pays the full cost of both architectures while capturing the benefits of neither.
Why most teams should start with a monolith
For most product engineering teams, especially those under 50 engineers or still finding product-market fit, a well-structured modular monolith is the highest-leverage starting point. This is not a conservative fallback. It is the architecturally defensible choice for the organizational stage most product companies are in.
The “monolith first” principle is direct. Build a clean modular monolith with enforced domain boundaries. Extract services only when a specific, observable bottleneck makes independent scaling or team autonomy necessary. Not in anticipation of scale that has not arrived yet.
A modular monolith delivers several concrete advantages in practice.
- Clean internal module boundaries. No module can access another module’s database or business logic directly. This constraint is what makes service extraction feasible later, when the team grows into it.
- A single deployment unit. Straightforward CI/CD and no service mesh or orchestration overhead.
- Full ACID transactions across the entire data model eliminate the need for distributed transaction patterns or Saga orchestration.
- One log stream and one call stack make debugging orders of magnitude faster than distributed tracing across multiple services.
Frameworks for enforcing modular monolith structure include Spring Modulith (Java), Django with app-based structure (Python), Rails engines (Ruby), and Laravel modules (PHP). The module boundaries that these frameworks enforce become service interfaces if extraction is needed later.
Twilio’s Segment quantified what the productivity return looks like. After consolidating 140+ microservices into one codebase, the test suite runtime dropped from one hour to milliseconds. Three engineers who had been spending most of their time on service reliability shifted back to product work. The team shipped 46 product improvements in the year after consolidation, compared to 32 the year before.
When microservices are worth the cost

Microservices are not wrong. They are expensive. The question is whether the specific value they deliver justifies what the team will pay to operate them in the monolith vs microservices trade-off. There are also clear cases when not to use microservices at all. The five conditions below are where the answer tips toward yes.
Independent scaling is a current, proven need
A named component, such as an image processing pipeline, recommendation engine, or payment service, needs to scale independently of the rest of the application. Vertically scaling the full monolith is no longer economical or technically feasible. The bottleneck is measured and observed in production, not hypothesized about future traffic.
Team structure already maps to service boundaries
The organization has 10 or more engineers working on separate business domains with separate product goals, separate backlogs, and separate leadership. Conway’s Law predicts this architecture. If teams are still sharing standup and sprint planning, the organizational structure is not there yet, and the architecture will reflect the gap within months.
Components have genuinely different technology requirements
One team is building a Python ML inference pipeline. Another is maintaining a Go API. A third is running a Java legacy integration. The technology divergence is real and driven by functional requirements, not team preference or hiring bias.
Compliance requires infrastructure-level isolation
Regulated environments in fintech, healthcare, and defense may require payment data, PII, and audit logs to be provably isolated at the infrastructure boundary. Separation at the application layer is not enough.
The operational foundation is already in place
CI/CD per service, distributed tracing, centralized log aggregation, service health dashboards, and on-call runbooks exist and have been tested under real incidents. Running microservices without this foundation is running blind.
Teams that haven’t built this layer yet can move faster by bringing in help. Eastgate’s cloud-native and DevSecOps team builds and validates the CI/CD, distributed tracing, and security automation foundation before a single service is extracted.
The inflection point most engineering teams reach is somewhere around 10 to 15 engineers per domain. At that headcount per domain, the coordination overhead of a shared codebase tends to exceed the operational cost of microservices. Below that threshold, microservices solve a problem the team does not yet have.
How to make the monolith vs microservices decision
Before choosing between a monolith and microservices, answer three diagnostic questions. The honest answers determine the right next step.
- Can each proposed service be independently deployed today without coordinating a release with another team? If the answer requires refactoring first, service boundaries are not clean. The right next step is enforcing domain boundaries inside the current codebase, not migrating to a new architecture.
- Does the team structure already map to those service boundaries? One team per service is an operational prerequisite, not an aspiration. If three engineers own five proposed services, the team does not have the capacity to operate them independently. Under operational pressure, the architecture will drift back toward a distributed monolith.
- Has the team identified a specific scaling or velocity bottleneck that microservices would solve? Name the bottleneck, the component, and the metric. “We expect to scale eventually” is a forecast, not a constraint. Architecture decisions driven by anticipated growth rather than observed friction are a common and expensive mistake.
If the answers to all three questions are not yes, the right next step is a modular monolith with enforced domain boundaries. Then, confirm all four of the following before starting a migration.
- Clean domain boundaries exist in the current codebase, with no circular module dependencies.
- CI/CD infrastructure is ready to build and deploy each service independently.
- Observability tooling is in place, covering distributed tracing, centralized log aggregation, and service health dashboards.
- Separate ownership per domain, with a named lead for each proposed service boundary.
If your team has cleared all four conditions but doesn’t have the bandwidth to execute the migration while keeping the current system live, Eastgate’s enterprise platform modernization practice handles phased service extraction with the monolith kept in production throughout.
Using monolith vs microservices to build AI products
For teams building AI-native products in 2026, the monolith vs microservices decision applies with an additional dimension.
A monolith handling model inference directly will hit memory and compute constraints differently from a web application. Adopting a full microservices architecture while still finding AI product-market fit compounds the usual operational cost with GPU and inference infrastructure overhead.
A modular monolith with inference as an isolated, swappable module is the lowest-risk starting point. Extract the inference service when load patterns are observed and understood, not before.
What the reversal stories actually teach

The pattern behind every reversal
The companies that reverted from microservices to monoliths were not making a statement about architecture in the abstract. They were correcting a mismatch between their organizational complexity and their architectural complexity. The service count had exceeded the team’s ownership capacity. Services that were supposed to be autonomous had accumulated dependencies that made independent deployment impossible.
Amazon Prime Video: Distributed components to a single service
Amazon Prime Video’s video quality monitoring system, built on AWS Step Functions and Lambda, failed at 5% of the expected load. The distributed components were tightly coupled at the data level, the kind of coupling that does not show up on an architecture diagram. Rebuilding it as a single service resulted in a 90% reduction in infrastructure costs. The fix was not better microservices tooling. It was removing the distributed architecture entirely.
Twilio Segment: 140+ services consolidated into one
Twilio Segment had already documented the productivity return from consolidation, as covered above. The reversal adds one more lesson. The 140+ services that accumulated were not all bad decisions individually. They accumulated because the team structure was not providing the clear ownership that each service needed to remain autonomous. The organizational gap produced the architectural gap.
The real lesson
The technical gains in each case, cost reduction and velocity improvement, followed from the organizational correction. Consolidation removed the infrastructure that was making coupling expensive to manage. The architectural simplification was the effect. The organizational realignment was the cause.
The lesson is not that microservices are the wrong choice. It is that premature microservices are expensive, and the cost compounds with every engineer-hour spent managing infrastructure rather than building product.
The bottom line on monolith vs microservices
For most teams, the right starting point is a modular monolith with clean, enforced domain boundaries. Extract a service when a specific bottleneck makes the trade-off clear. A monolith-to-microservices migration works best as a phased extraction, not a full rewrite.
The distributed monolith is what the monolith vs microservices decision is really trying to prevent. Getting it right means choosing an architecture that fits the team today and building it with the internal structure that allows it to evolve as the team grows.
Ready to evaluate your current architecture and figure out whether you are building a distributed monolith without realizing it?
Ready to Build Your Next Product?
Start with a 30-min discovery call. We'll map your technical landscape and recommend an engineering approach.
Contact usGet Industrial Insights Delivered to Your Inbox
By clicking "Subscribe" you agree to allow Eastgate Software to send newsletter emails to your address. For more information, please read our Privacy Policy.
About The Author
CEO & Founder, Eastgate Software
Ha Bui is the CEO and Founder of Eastgate Software. Since 2014, he has led the company's 12+ year engineering partnerships with Siemens Mobility and Yunex Traffic, building a 200+ engineer organization that delivers mission-critical ITS, FinTech, and enterprise software to German engineering standards.

