Do You Really Need Microservices?
Microservices emerged as a software architecture style in the early 2010s. Although the concept of breaking down applications into smaller, loosely coupled services can be traced back to earlier practices, such as SOA (Service-Oriented Architecture) from the 2000s, microservices gained significant popularity following key publications and case studies. In 2014, Martin Fowler and James Lewis published their influential article "Microservices," articulating the principles of microservices as an evolution of SOA with a focus on independently deployable services, decentralized data management, and technology diversity. Around the same time, large tech companies such as Netflix and Amazon publicly described their successful implementations of microservices, further solidifying the architecture's relevance in modern software development.
Since then, microservices have been widely adopted and are often seen as the default choice for modern systems, especially in startups. They promise independent deployments, team autonomy, and flexible scaling. The prevailing mindset in many startups is "we need to scale," but this expectation is often unrealistic for systems that may never reach the scale that would justify the complexity. In the right context, those benefits are real. Still, a growing number of teams are finding that microservices introduce more complexity than their systems actually require.
This has led to a noticeable shift in how teams think about architecture. Rather than asking how quickly they can move to microservices, many are stepping back and asking whether they are needed at all.
Where microservices can make sense
Microservices tend to work best when systems are large, domains are clearly separated, and teams can own services end to end. They can be effective when different parts of a system truly need to scale independently or evolve at different speeds. These conditions do exist, but they are less common than architecture diagrams might suggest.
Outside of those scenarios, the overhead of distributed systems can become a burden. Network calls replace simple function calls, data consistency becomes harder, and day-to-day development often slows as the number of services grows.
What happens in practice
A well-known example comes from Amazon Prime Video. In March 2023, their engineering team published a case study about their video quality monitoring service, which analyzes every stream in real time for defects. The original system was built using AWS Step Functions and Lambda—a distributed, serverless architecture that relied on orchestration across multiple components.
The team encountered hard scaling limits at around 5 percent of expected load. The orchestration overhead and the cost of moving data between components through S3 made the system impractical at scale. By consolidating the workflow into a single process running on EC2 and ECS, they reduced infrastructure costs by over 90 percent and eliminated the scaling bottleneck.
It is worth noting that this change applied specifically to the monitoring pipeline, not to Prime Video's streaming infrastructure as a whole. The case also sparked debate in the community. Some argued that moving from a distributed serverless system to a single-process application on dedicated compute was not a true shift from microservices to monolith, but rather a pragmatic correction of an overly distributed design. The original blog post was later removed by Amazon, though it remains widely archived and cited.
The key lesson was not that microservices were "wrong," but that the system did not benefit from being split apart in that particular way. Keeping the workflow in one place made it easier to reason about, easier to operate, and cheaper to run.
Reference: Amazon Prime Video architecture case (archived original)
Twilio Segment reached a similar conclusion. Their event delivery system grew to more than 140 microservices, each handling different integrations. While this offered isolation in theory, in practice it created operational drag. Developers spent large amounts of time managing repositories, deployments, and failures across services.
Eventually, the team merged those services back into a single codebase and deployment. Testing became faster, operational load decreased, and developer productivity improved. Some trade-offs remained, but the overall system was easier to work with and maintain.
Reference: Twilio Segment: Goodbye, Microservices
The quiet return of the modular monolith
These stories help explain why modular monoliths are becoming more common. A modular monolith keeps a system as a single deployable application, but enforces strong internal boundaries. Code is organized into modules with clear responsibilities and well-defined interfaces, while remaining in the same process.
This approach avoids many of the costs associated with microservices. There is no network overhead between modules, no need for service discovery, and no distributed data consistency problems. At the same time, developers still get structure and separation inside the codebase.
For many teams, this strikes a practical balance. It allows systems to grow in complexity without immediately paying the operational cost of distribution. If a module later needs to be split into its own service, the boundaries are already in place.
Research and industry experience both suggest that decomposing systems into services is difficult to get right and often introduces new challenges alongside the intended benefits.
Reference: To Microservices or Not to Microservices?
Infrastructure and cost considerations
Architecture choices also have financial consequences. Microservices often pair naturally with managed services from large cloud providers. While convenient, this combination can become expensive, especially as the number of services and internal traffic increases.
In contrast, many teams find that running containerized applications on virtual machines with a smaller provider is both manageable and cost-effective. Tools like Kubernetes or Docker Swarm are mature and well understood. For teams comfortable with infrastructure, operating their own clusters can be simpler than managing a complex web of managed cloud services.
Choosing what fits
There is no single "correct" architecture. Microservices are useful in some contexts, but they are not a requirement for building scalable or maintainable systems. Modular monoliths offer a clear, practical alternative that works well for many teams and products.
Starting with a simple, well-structured system and introducing complexity only when it is clearly justified remains a sound approach. In many cases, staying monolithic longer turns out to be the easier path to maintainability, performance, and predictable costs.
Additional reference: Docker: Do You Really Need Microservices?