DEV Community

Mustafa ERBAY
Mustafa ERBAY

Posted on • Originally published at mustafaerbay.com.tr

Microservices Are Not Always The Right Answer

In my career, an architectural decision, swayed by the allure of the word "microservices," ended up costing me far more than a line of code. For years, I've been building systems, managing networks, and developing enterprise software; one of the biggest misconceptions I've seen in this process is the belief that every project needs a microservice architecture.

In my opinion, while this architectural pattern provides incredible benefits in the right scenario, in the wrong hands or when applied unnecessarily, it can turn into an operational nightmare. As a system architect, I've experienced countless times how critical it is to weigh the pros and cons before blindly jumping into every new trend.

The Microservice Dream and Realities

The promises of microservices always sound appealing: independent teams, rapid deployment, technology diversity, flexible scalability. Enticed by these promises, I too embarked on this path for a medium-sized project at one point. The goal was to separate specific ERP modules (such as shipping or invoicing) into distinct services.

However, the realities were very different from the theory. The hidden dependencies between modules turned out to be much more complex than we anticipated. Deploying each service separately, managing CI/CD pipelines, and ensuring observability was many times more burdensome than the initial simple monolithic structure.

⚠️ The Trap of Premature Optimization

Often, moving towards microservices with the thought of "we'll scale later" is falling into the trap of premature optimization. Unnecessarily complicating the system when there's no proven performance or scalability issue yet negatively impacts development speed and operational efficiency.

When to Use Monolith, When to Use Microservices?

The answer to this question is much deeper than the cliché "it depends." In an ERP system for a manufacturing company, business workflows are often tightly coupled and proceed within a transaction chain. Here, a monolith or at least a well-modularized monolith structure might be much more sensible than dealing with the complexity of distributed transactions.

On the other hand, in a large Turkish e-commerce site, areas like product search, cart, payment, and order management can operate quite independently. Each might have its own scaling needs and different load profiles. In such a scenario, microservices can truly shine, because you can scale and deploy each service independently. I've also used microservice-like structures for the financial calculators of my own side product, which receive high traffic independently of the main backend.

Overlooked Costs and Operational Burden

One of the biggest challenges brought by microservices is the operational burden. Where you once managed a single PostgreSQL instance and a single Nginx reverse proxy, you now have to manage separate databases, Redis caches, Nginx configurations, and systemd units for each service. With Journald logs streaming from dozens of sources, even tracing a simple error becomes time-consuming.

While container orchestration (even with Docker Compose) alleviates this burden somewhat, I encounter new problems like container memory limits, disk I/O issues, or build OOM errors. Especially on the network side, issues like latency in inter-service communication, MTU/MSS mismatches, and hidden DNS problems present details you would never consider in a monolithic structure. Last month, in a client project, it took us days to discover that a simple API request was passing through dozens of different services and failing due to rate limiting or network timeout at each hop.

My Preference and Recommendation

Personally, I prefer a "modular monolith" approach for most projects. I start as a single deployable unit, but design its internal architecture with clear boundaries (domain boundaries) and well-defined interfaces. This allows me to implement patterns like event-sourcing or CQRS within the monolith.

If, over time, a specific section genuinely requires independent scaling, a different technology stack, or different team responsibility, then I can safely separate that piece. But this decision comes after a real need and a bottleneck proven by observability metrics, never just because "it's the trend."

So, what are your experiences on this topic? Have you ever been swayed by the allure of microservices in your career and regretted it, or, conversely, made the right decision? I'm curious to hear your thoughts in the comments.

Top comments (0)