Logo
Logo

Why Microservices Usually Hurt Projects

March 4, 2025. Paul Kryvenko. 11 min read.

Microservices: What They Are and Aren’t

Microservices are an architectural style where an application is divided into a set of small, autonomous services that operate independently and interact through APIs. Each microservice:

  1. Deploys and scales independently from other services.
  2. Performs a clearly defined business task.
  3. Communicates with other services through well-defined interfaces.
  4. Can be in its own language and typically has its own separate database.
Monolith vs MicroservicesMonolith on the left / Mircoservices on the right

These key distinctions inspire trust and confidence in the predictable development, operation, and maintenance of the application. However, over years of working with this architecture, we have identified many specific pitfalls.

Unveiling the Hidden Risks of Microservices

At first glance, scaling seems instantaneous and effortless, but in reality, that’s not always the case. The scaling process itself generally proceeds smoothly, yet configuring and maintaining the cluster can become significant time and resource drains. Moreover, the more interactions there are—which microservices inherently involve—the costlier mistakes become.

A good example is a case with our client who consulted us about an issue. They had an internal team that developed a microservice-based server application but made a design error. This mistake occurred at the transport layer, leading to excessive generation of tracing information. As a result, the increased traffic cost the client an additional $10k per month. Naturally, the problem lay in design errors, not the microservice model itself. While microservices can be effective, their maintenance becomes overly complex with limited resources and lack of expertise, making this architecture the wrong choice for their team and budget.

Another common promise of microservice architecture is freedom in choosing the technology stack. At first glance, this seems like a strength: the team can select technology based on needs and tasks. However, in most projects, such flexibility is unnecessary since one agreed-upon stack covers all tasks. Each added technology increases project complexity, impacting budget, timelines, and release quality.

One of the most painful points is the transport layer. The absence of a clear and well-designed data exchange contract between services is particularly challenging. Without agreed-upon interaction agreements, microservices start “speaking different languages.” Minor differences in clients for the same message broker or protocol can cause numerous unpredictable bugs in the system. Consequently, this affects cluster stability and the reliability of updates. Paradoxically, this negates one of the main advantages of microservices: independence and resilience.

Finally, there’s the widely touted benefit of independent releases. The idea is to update individual modules without affecting the entire system. This approach should increase update frequency and minimize release risks. But in practice, it’s different: a unique role emerges whose task is to check the compatibility of microservice versions with each other. We are undoubtedly in an architectural crisis if our system requires a person on whom the “independent system” depends.

Need help scaling your SaaS or E-commerce platform?

The industry has shifted from engineering towards architectural trends. Microservices are used as the de facto standard across various scenarios, even when they don’t address any specific problem. As a result, we end up with a poorly managed setup masked by a layer of microservices, leading to budget overruns and unpredictable releases.

There’s a more interesting trend here—businesses increasingly adopt corporate solutions. However, this rarely helps in effectively solving project tasks. A striking example is Telegram—created and developed by a team of just a few dozen people, yet it serves a billion users. Therefore, it’s crucial to focus on the real needs of the project and build architecture based on those needs. It’s essential to remember that corporations have unlimited resources and can afford to abandon projects one after another, but this approach is fatal for the rest of the world.

Aligning Architectural Choices with Business reality

We have already mentioned that architecture should be based on real needs. But what exactly is a real need? Does it mean reaching a certain number of modules, or deploying a new release every week? Let’s start by defining need as a condition or goal for achieving a business result. If a need lacks a specific, predictable business outcome, it’s more of a wish than a real necessity.

This approach helps filter out the unnecessary and make architectural decisions based on objective factors rather than preferences. We would like to share real cases from my experience that highlight the importance of focusing on business results.

In the first project, the architecture was built “for scale,” but the complexity of the project never caught up. A classic situation: a startup with 3 backend developers, a part-time DevOps, microservices, Kubernetes, and tracing. The project was developed for 9 months, with half the time spent on developing and deploying infrastructure that wasn’t even needed. Investments dried up, and the project was put on hold awaiting new ones—which almost always means death.

In the second example, the situation was the opposite—the project outgrew its architecture. This was an online store with a simple stack—a monolith on PHP. Over time, it rapidly gained popularity, especially during holiday seasons. Traffic increased, but the architecture and technical debt remained the same. During peak times, the server crashed and users left—one day of downtime cost more than saving on architecture. There’s nothing wrong with starting with a simple stack, but ignoring technical limitations that arise as the project grows isn’t wise. Architecture isn’t needed at the start, but it’s better not to wait until it becomes critically necessary.

The Right Time, Place, and Context for Microservices

However, it should be noted that microservices themselves are not the problem. The issue arises when trying to use them inappropriately. They find their place within constraints that are difficult to resolve otherwise.

  • Working on a project with a large, distributed team—when we say “large,” we don’t mean 10 people. Microservices help reduce the risk of conflicts, blockages, and structural degradation. This architecture allows responsibilities to be distributed, reducing the density of communications. In this context, it’s more of an organizational solution than a technical one.
  • Another example is heterogeneous and loosely connected business domains. For instance, consider Square: the payment solutions module and the customer management block perform entirely different tasks and require different isolation. Combining these modules into one would create artificial intersections, making changes interdependent and complicating development. Microservices allow such modules to be physically separated, minimizing mutual dependencies.
  • Another point is the need for different technologies. However, it is important to understand what we mean by necessity or demand. Returning to our chapter on needs, a need is a condition or goal for achieving a business result. An example is the requirement for integration with a low-level API available only in a specific language, due to security or legacy reasons. In such cases, using a microservices approach is not an experiment or whim, but a way to maintain project flexibility.

Final Thoughts and Recommendations

  • Firstly, it’s essential to understand the real business need for microservices rather than chase trends. If the architecture far exceeds the actual complexity of the project, it offers no advantages and only consumes the budget.
  • Secondly, avoid overusing diverse technologies: if one stack suffices for the project, variety will only complicate maintenance.
  • The third important note is to ensure clear communication between services at the transport level. In most cases, the transport layer becomes the point of failure.

Microservices shine when there is a truly distributed team, fundamentally different business domains, or a need for a diverse technological stack; otherwise, it can easily become an extravagant and maintenance-heavy solution.

Need help scaling your SaaS or E-commerce platform?