Should We Actually Build Microservices?
ArchitectureMicroservicesEngineering

Should We Actually Build Microservices?

DD

Demir Danış

April 28, 2025 · 7 min read

At the start of nearly every new project these days, the same question surfaces almost instinctively: "Should we build this as microservices?" The question itself isn't wrong. What's often missing is the follow-up: "Why? What problem would that actually solve?" Too frequently, the choice is driven by trend, peer pressure, or a vague sense of obligation rather than a clear engineering rationale.

Why Microservices Existed in the First Place

Microservices emerged as a direct response to real, painful problems that large monolithic systems produce at scale:

  • Deployments in large monoliths became slow, risky, and increasingly difficult to coordinate
  • One team's change could silently break another team's production environment
  • Scaling a single hot component meant scaling the entire application alongside it

The promise of microservices was specific: independent deployability, team-level ownership with clear service boundaries, and the ability to scale individual components in isolation. The goal was never to decompose for the sake of decomposition. It was to gain autonomy.

What We Often Build Instead

In practice, the picture frequently looks quite different. Consider a scenario that will be familiar to many engineers: a single team maintaining 10 to 15 microservices, with every engineer committing to every service. The services are nominally independent but deployed together as a unit. Kubernetes exists in theory but runs a single instance of each service with no horizontal scaling per service. There is no event-driven communication — services call each other synchronously in chains.

At this point, it's worth asking honestly: where is the microservices architecture we set out to build? If we weren't going to use independent deployment, team ownership, or elastic scaling — why did we absorb all of the operational overhead that comes with this approach?

The Questions We Should Ask First

Before choosing microservices — or any architectural pattern, technology, or framework — the right discipline is to work through these questions explicitly:

  • What specific problem are we solving with this choice?
  • Do we have independent teams who need autonomous deployment pipelines?
  • Are there components with genuinely different scaling profiles?
  • Do we have the operational maturity to run a distributed system — observability, service discovery, failure handling?
  • What is the real cost of this approach versus a simpler alternative?

If the honest answers don't justify the complexity, that's a signal worth taking seriously.

The Case for a Well-Designed Monolith

A well-structured monolith with clear domain boundaries will, in many contexts, outperform a poorly conceived microservices architecture on every dimension that matters: development velocity, operational simplicity, debuggability, and long-term maintainability. Microservices chosen at the wrong moment and for the wrong reasons don't reduce complexity — they redistribute it into the infrastructure, into inter-service contracts, and into the cognitive load of every engineer on the team.

This isn't an argument against microservices. Engineers working in this space should understand them deeply — both the theory and the practice. At the right scale and organisational maturity, microservices deliver exactly what they promise. The point is that the pattern must be earned by the problem, not assumed by default.

Engineering Is Optimisation Under Constraints

Engineering is the discipline of solving problems with the resources available — no more, no less. A solution that introduces unnecessary complexity isn't clever; it's a liability. Sometimes the most sophisticated thing an engineering team can do is choose the simpler path deliberately, with a clear understanding of what they're trading off and why.

What we often need isn't more services. It's clearer boundaries, better-defined domains, and the discipline to resist complexity for its own sake.