Microservices Architecture — What It Is and When It Makes Sense
At some point in almost every technology project, someone says it: we should break this into microservices. It is said with confidence. It is rarely followed by a clear explanation of what that actually means, what it will cost, or whether it is the right call for where the project is right now.
Microservices are one of the most genuinely useful architectural patterns in software — and one of the most consistently oversold. Teams adopt them because Netflix and Amazon use them, then spend the next two years fighting distributed systems complexity instead of building product. The pattern is not the problem. The timing is.
This post explains what microservices architecture actually is, how it differs from a monolith, what you genuinely gain and what you genuinely give up, and — most importantly — when the switch makes sense and when it does not.
🔗 Related reading
This post pairs well with Docker and Containers — The Why — microservices almost always run in containers, and understanding why containers exist makes the architecture click. Also worth reading: Event-Driven Architecture — the communication pattern that makes large microservices systems actually work.
What a monolith actually is
A monolith is an application where all the code — the user interface, the business logic, the data access layer — lives in one codebase and deploys as one unit. Change anything, deploy everything.
This gets a bad reputation it does not fully deserve. Every serious application starts as a monolith. It is the sensible starting point. One codebase is simple to develop, simple to test, and simple to deploy. When a team is small and the domain is not yet fully understood, a monolith lets you move fast.
The problems arrive with scale — not size of data, but size of team and complexity of change. When fifty engineers are all committing to the same codebase, a single broken change blocks everyone’s deployment. When one component needs to scale — say, your payment processor is under heavy load but your notification service is idle — you cannot scale them independently. You scale the whole thing or nothing.
📌 Key takeaway
The monolith is not the enemy. An unexamined monolith — one that has grown beyond the team’s ability to reason about it — is.
What microservices are — and how they differ
Microservices architecture breaks an application into a collection of small, independently deployable services. Each service handles one business capability — payments, authentication, notifications, inventory — and communicates with other services over the network, typically via REST APIs or a message queue.
The critical word is independently. Each service has its own codebase, its own deployment pipeline, and its own data store. The payment service does not share a database with the authentication service — they talk through defined interfaces. That boundary is what makes them independent.
| Aspect | Monolith vs Microservices |
|---|---|
| Codebase | Monolith: one shared codebase. Microservices: separate codebase per service. |
| Deployment | Monolith: deploy everything together. Microservices: deploy each service independently. |
| Data | Monolith: shared database. Microservices: each service owns its own data store. |
| Scaling | Monolith: scale the whole application. Microservices: scale individual services. |
| Communication | Monolith: in-process function calls. Microservices: network calls via API or message queue. |
| Failure | Monolith: one failure can bring down the whole app. Microservices: failure is isolated to one service. |
| Team ownership | Monolith: everyone owns everything (and nothing). Microservices: one team owns one service end-to-end. |
📝 Note
Amazon is the canonical example of this transition. By the early 2000s, the original Amazon monolith had become a deployment bottleneck — every change required coordinating across hundreds of engineers. Jeff Bezos issued an internal mandate: every team would expose its capabilities as a service. The architecture that came out of that mandate is what eventually became AWS.
What microservices actually give you
Four genuine benefits — not marketing, not what the conference talks say. What actually changes when microservices are working well.
Independent deployability
The payment team can ship a fix at 2pm on a Tuesday without waiting for the notifications team to finish their feature. No release coordination. No shared deployment queue. This is the one benefit that makes everything else worth it at scale — and it is only possible because each service has its own codebase and deployment pipeline.
Fault isolation
When the recommendation engine crashes in a microservices system, users still check out. The payment service keeps running. In a monolith, that same crash often takes down the whole application. Netflix migrated to microservices starting in 2008 after a database corruption incident took DVD shipments completely offline. Fault isolation was the core requirement.
Independent scaling
Scale the service that needs it, not the service that does not. If your search service is under load during a product launch but your reporting service is idle, you scale search. In a monolith you would be scaling everything, including the parts that do not need it.
Team autonomy
One team owns one service — design, build, deploy, monitor, on-call. Amazon calls these two-pizza teams: small enough to be fed by two pizzas. The team moves at their own pace, makes their own technology choices, and ships without requiring sign-off from every other team in the organisation.
✅ Best practice
Each service should be owned completely by one team. If two teams share ownership of one service, you have not achieved the autonomy microservices promise — you have just moved the coordination problem inside a service boundary.
What microservices actually cost you
This is the section most posts bury or skip. Every benefit above comes with a real cost. These are not edge cases — they are the standard experience of moving from a monolith to microservices.
Distributed system complexity
In a monolith, calling a function never fails due to a network timeout. In a microservices system, every service call is a network call — and network calls fail, timeout, and return inconsistent results. You now need to handle partial failures, retry logic, and circuit breakers for things that used to be in-process.
Observability overhead
When something goes wrong in a monolith, you check one log file. When something goes wrong in a microservices system, the failure might have originated in any one of twenty services.
You need distributed tracing, centralised logging, and service health dashboards from day one — not as an afterthought. Without them, debugging production issues becomes genuinely painful.
Data consistency
Each service owns its own database. That means the same customer might exist in the payment service database and the notification service database — and keeping them consistent requires careful design. Transactions that span service boundaries do not exist in the simple sense. You design around this with eventual consistency and careful event handling.
Infrastructure investment
Microservices need container orchestration, service discovery, API gateways, and a proper CI/CD pipeline for every service. Teams need dedicated platform engineering capacity to set this up and maintain it. This is not a part-time job.
⚠️ Warning
A distributed monolith is worse than either. This is what happens when you split the code into separate services but keep a shared database or tightly coupled dependencies between them. You get all the complexity of microservices with none of the independence. Design the service boundaries before you split — not after.
When to use microservices — and when not to
The honest answer is that most applications should start as a well-structured monolith and extract services only when a specific, justified need appears. The Strangler Fig pattern — gradually extracting services from a monolith one at a time — is the most reliable migration path for teams that have earned the move.
The signals that tell you a service boundary is justified are concrete. Not architectural preference. Not what Netflix does. Concrete signals.
| Signal | Extract to a service when… | Stay with the monolith when… |
|---|---|---|
| Scaling | One component needs to scale at 10x the rate of everything else | All components scale together — traffic is uniform |
| Release cadence | One team ships five times a day; another ships once a month | Teams share a release cycle and that works fine |
| Team ownership | More than 50 engineers working in the same codebase | Under 20 engineers who can align in regular communication |
| Technology | One component genuinely needs a different language or database | One stack serves all needs — no hard requirement for diversity |
| Failure impact | One component’s failure must not be able to take down the whole system | Acceptable for the whole app to go down together during rare failures |
💡 Practical tip
The modular monolith is worth knowing about. It is a monolith with well-defined internal boundaries — modules with clear interfaces, no cross-module database access, and clean separation of concerns. It gives you most of the organisational clarity of microservices at a fraction of the operational cost. When the time comes to extract a service, a modular monolith makes that extraction significantly easier.
Conway’s Law — why the org chart matters as much as the architecture
In 1968, Melvin Conway made an observation that has aged better than almost anything else in software: organisations that design systems are constrained to produce designs that are copies of their communication structures.
In plain English: your architecture reflects your team structure. If your teams are siloed by technical specialty — one frontend team, one backend team, one database team — your architecture will be siloed the same way. You will end up with a frontend service, a backend service, and a shared database. Which is not microservices. It is a distributed monolith.
Microservices done well require teams structured around business capabilities, not technical layers. One team owns the entire payment capability — frontend, backend, database, deployment. The service boundary and the team boundary are the same line. When they are not the same line, the architecture will drift toward the team structure eventually — and usually in the worst possible way.
📌 Key takeaway
If you restructure your architecture without restructuring your teams, you have not adopted microservices. You have just added network calls to a monolith. The organisational change is as important as the technical one.
At a glance — microservices architecture
| Concept | One-line summary |
|---|---|
| Microservices architecture | An application broken into small, independently deployable services — each owning one business capability and its own data. |
| Monolith | One codebase, one deployment, one database — simple to start, increasingly costly to change at scale. |
| Modular monolith | A structured monolith with clean internal boundaries — the recommended starting point before extracting services. |
| Independent deployability | Each service ships on its own timeline without coordinating with other teams — the core benefit of microservices. |
| Fault isolation | A failure in one service does not cascade to others — each boundary is a blast radius limiter. |
| Distributed systems complexity | Every service call is a network call that can fail, timeout, or return partial results — this cost is real and unavoidable. |
| Strangler Fig pattern | Gradually extract services from a monolith one at a time — the most reliable migration path. |
| Conway’s Law | Your architecture reflects your team structure. Restructure teams and architecture together, or the benefits will not materialise. |
| Two-pizza team | Amazon’s term for a service team small enough that two pizzas can feed them — the right size for owning one microservice end-to-end. |
What to take away
Microservices are not a technical decision. They are an organisational decision with technical consequences. The architecture you end up with reflects how your teams communicate — Conway’s Law is not a suggestion, it is a description of what will happen whether you plan for it or not.
The teams that make microservices work invest in two things before anything else: clear service boundaries defined around business capabilities, and the platform engineering capacity to deploy, observe, and operate distributed services safely. Neither of these is glamorous. Both are what separate a functional microservices system from a distributed mess.
Start with a modular monolith. Define clean boundaries. Extract services when you have a concrete, justified reason — not because the architecture looks good on a diagram. The moment a component genuinely needs to scale independently, or a team genuinely needs to ship without coordinating with every other team, is the moment a service boundary earns its place. Not before.
🔗 Related posts on this site
Docker and Containers — The Why — microservices almost always run in containers. This post explains why containers exist and what problem they actually solve.
Event-Driven Architecture — the communication pattern that handles async service-to-service communication in microservices systems without tight coupling.
How Kubernetes Works — The Mental Model — Kubernetes is the orchestration layer that keeps microservices running at scale. The logical next post after this one.
REST API Design Principles — services talk to each other via REST APIs. Getting the design right matters more when there are dozens of service boundaries.
Published on rakeshnarayan.com — Articles
URL: https://rakeshnarayan.com/articles/microservices-architecture-what-it-is-and-when-it-makes-sense/



Did you enjoy this article?
Let me know — it takes one click.
0 Comments
Leave a Comment
Your comment has been submitted and will appear after review.