We now know what a microservice is. The natural next question is: are they worth it? The honest answer is "it depends", and this lesson exists so that "it depends" stops being vague. We will walk in detail through the advantages the architecture offers and, with the same seriousness, the disadvantages it brings along. Understanding both sides matters because, as we will see, almost every advantage has an associated cost: you do not get selective scaling without taking on network complexity, or independent deployments without managing contracts, or team autonomy without investing in automation.

We will illustrate every point with a concrete situation at TechCorp, the online store that serves as the running example of the course. We will also present the famous "eight fallacies of distributed computing", a list of mistaken assumptions that every developer moving from a monolith to distributed services eventually discovers, often the hard way. In this lesson we will not yet make the structured comparison with the monolith (lesson 01-03) or give decision criteria (lesson 01-04); here the goal is to understand clearly what you gain and what you pay.

Contents

  1. Advantages of microservices
  2. Disadvantages of microservices
  3. The eight fallacies of distributed computing
  4. Summary table: each advantage and the cost it brings
  5. Common mistakes and tips
  6. Exercises
  7. Conclusion

  1. Advantages of microservices

1.1 Selective scaling

In a monolith, if one part of the system needs more capacity, you have to replicate the whole application. With microservices you scale only the service that needs it.

Situation at TechCorp: during Black Friday, catalog browsing traffic multiplies by twenty, but the number of orders "only" triples and customer data lookups barely change. With the current monolith, Marta has to rent servers to replicate the entire store, including modules that are not under pressure. With separate services, ten instances of catalog-service and two of orders-service are brought up, and everything else stays as it is. Both the infrastructure bill and the risk of over-provisioning go down.

flowchart LR
    subgraph Black Friday
        CAT1[catalog #1]
        CAT2[catalog #2]
        CAT3[catalog ...]
        CAT10[catalog #10]
        ORD1[orders #1]
        ORD2[orders #2]
        CUS1[customers #1]
        NOT1[notifications #1]
    end

1.2 Independent, frequent deployments

Each service is deployed separately. A small change in one service does not force you to rebuild, test and deploy the whole system, so you can deploy more often and with less risk.

Situation at TechCorp: Luis's team fixes a bug in the shipping cost calculation. Today, in the monolith, that change waits for the weekly Friday deployment together with thirty other changes from five teams; if something breaks, someone has to work out which of the thirty caused it. With a separate orders-service, Luis deploys on Tuesday morning, in ten minutes, and if anything goes wrong he knows exactly what to roll back.

1.3 Team autonomy

Each team owns one or more services and decides how to build them, when to deploy them and how to operate them. Coordination between teams (meetings, waiting, dependencies) goes down and speed goes up.

Situation at TechCorp: today, to add a column to the orders table, Luis has to check with the Notifications team (which reads that table to compose emails) and with the Payments team (which updates it when charging). With separate services, each one has its own data and its own API: Luis changes whatever he wants on the inside as long as he honors the public contract.

1.4 Technological heterogeneity

Each service can use the technology best suited to its problem: another language, another database, another version of a library. And you can try out a new technology in a small service without betting the whole system on it.

Situation at TechCorp: the catalog has products with highly variable attributes (a T-shirt has sizes and colors; a laptop, processor and memory). In PostgreSQL that forces awkward generic tables. With catalog-service isolated, the team can use MongoDB, whose flexible documents fit far better, without orders or payments having to leave PostgreSQL. In this course we will keep Node.js in every service for teaching simplicity, but nothing would stop one of them from being written in Go or Java.

1.5 Fault isolation

A failure in one service does not have to bring down the rest, as long as the system is designed to tolerate one part not responding.

Situation at TechCorp: the email delivery provider suffers an outage and the notifications module starts piling up errors and consuming memory. In the current monolith, that module shares a process with everything else: the memory leak ends up taking down order creation too, and the whole store stops selling because of emails. With a separate notifications-service, emails are delayed, but orders keep being created and charged. (Careful: this isolation is not automatic; it has to be designed, and we will cover it in module 6.)

1.6 Maintainability of small codebases

A service of a few thousand lines is far easier to understand, test and modify than a monolith of hundreds of thousands. A new developer becomes productive sooner, tests run in seconds, and "old" code can be rewritten service by service.

Situation at TechCorp: a developer joining the Payments team today needs weeks to understand the monolith before touching anything, because any function can have effects anywhere. With a well-bounded payments-service, in a couple of days they know the whole codebase and can start contributing with confidence.

  1. Disadvantages of microservices

Now, with the same honesty, the price.

2.1 Complexity of a distributed system

What used to be a function call inside the same process is now a network request to another process, which may be down, slow or running another version. Problems appear that did not exist before: timeouts, retries, idempotency, message ordering, contract versioning, service discovery. There are more moving parts and more ways for something to fail.

Situation at TechCorp: in the monolith, createOrder calls reserveStock and, if it fails, the order is not created, end of story. With separate services, orders-service sends a request to inventory-service, gets no answer within three seconds... and does not know whether the stock was reserved or not. Does it retry and risk reserving twice? Does it cancel and risk leaving stock locked? Every one of those decisions now has to be made explicitly.

2.2 Latency and network failures

A call inside the same process takes nanoseconds; an HTTP call between services, milliseconds, and on top of that it can fail. A flow that in the monolith went through five functions now goes through five services and adds up their latencies.

Situation at TechCorp: the product detail page needs the product (catalog), available stock (inventory) and customer reviews (customers). Three 20 ms calls that in the monolith were three SQL queries in the same process are now three network hops, and if one of them takes 2 seconds, the whole page takes 2 seconds.

2.3 Data consistency

With a single database, a transaction guarantees "either everything happens or nothing does". With one database per service there are no longer transactions spanning several services: you have to accept eventual consistency and design compensation mechanisms.

Situation at TechCorp: today, in a single SQL transaction, the order is inserted, the stock is decremented and the payment is recorded; if the payment fails, everything is rolled back. With three different databases, if the payment fails after the stock has been decremented, someone has to give back that stock explicitly. That "someone" is a pattern called saga, studied in lesson 02-05.

2.4 Harder testing and debugging

Testing an isolated service is easy; testing that ten services work well together is not. And when something fails in production, the error may be in any of the services the request went through, each with its own logs.

Situation at TechCorp: a customer complains that their order shows as "paid" but the confirmation email never arrived. In the monolith, you open a single log file and follow the request. With six services, you have to look in six places, correlate by a common identifier and reconstruct the sequence. Without distributed tracing (module 6) this is a nightmare.

2.5 Operational and infrastructure cost

Each service needs to be built, packaged, deployed, monitored, scaled and secured. Six services are six pipelines, six metrics dashboards, six sets of alerts, six databases with their backups. On top of that, you need new pieces the monolith did not: a message broker, a gateway, an orchestrator, observability tooling.

Situation at TechCorp: today Marta has one application server and one database. Tomorrow she will have a Kubernetes cluster, RabbitMQ, five databases, Prometheus, Grafana, Loki, Jaeger and a gateway. Someone has to know how to operate all of that, and it is not free, in money or in people.

2.6 Organizational complexity

Microservices presuppose autonomous teams with end-to-end responsibility. If the organization is not ready for that (teams per technical layer, a single operations team you have to ask for permission, highly centralized decisions), the architecture collides with the structure and the architecture loses.

Situation at TechCorp: today there is "the back-end team", "the front-end team" and "the systems team". If the services are split but that structure is kept, every deployment of orders-service will still need approval from systems and coordination with front-end, and the promised autonomy will never materialize.

2.7 The risk of the "distributed monolith"

This is the worst of both worlds: the complexity of a distributed system without the advantages of autonomy. It happens when services share a database, when they all have to be deployed at once because their contracts change in lockstep, or when one cannot work without synchronously calling five others.

Situation at TechCorp: a rushed attempt to "do microservices" splits the code into six processes, but all of them remain connected to the same PostgreSQL database. Result: every schema change requires coordinating six deployments, the network adds latency and failures that did not exist before... and nothing has been gained. This risk is so important that we will come back to it in lesson 01-04.

  1. The eight fallacies of distributed computing

In the 1990s, engineers at Sun Microsystems (Peter Deutsch and others) listed a series of false assumptions that programmers tend to make when they start building distributed systems. Decades later they are just as valid, and they are the underlying reason for almost all the disadvantages we have just seen.

# Fallacy (what is wrongly assumed) The reality Practical consequence at TechCorp
1 The network is reliable Packets get lost, connections drop, services restart. orders-service must retry the call to inventory-service carefully and plan for never getting an answer.
2 Latency is zero Every network hop costs milliseconds, sometimes seconds. Chaining five synchronous calls to display a product is a bad idea; better to aggregate or cache.
3 Bandwidth is infinite Moving large volumes between services saturates the network and costs money. Do not send the whole catalog in every event; send identifiers and the bare essentials.
4 The network is secure Anything traveling over the network can be intercepted or spoofed. Encrypt communication between services and authenticate them to each other (module 7).
5 Topology does not change Instances appear, disappear and change address constantly. You cannot hard-code "inventory is at 10.0.0.5"; you need service discovery (lesson 03-05).
6 There is one administrator Different teams manage different parts with different criteria. Common standards for logs, metrics and deployment so the system is operable.
7 Transport cost is zero Serializing, sending and deserializing data consumes CPU, memory and time. Choose efficient formats and avoid unnecessary calls.
8 The network is homogeneous Different versions, languages, protocols and vendors coexist. Clear, versioned contracts (lesson 03-06) so the mix does not break anything.

The lesson they leave is easy to state and hard to internalize: when you move to microservices, the network stops being a detail and becomes part of the design. Every call between services must be designed on the assumption that it may fail, be slow, or arrive twice.

  1. Summary table: each advantage and the cost it brings

This table is probably the most useful thing you can take away from the lesson. Each row pits an advantage against the price you have to pay to actually obtain it.

Advantage Cost or disadvantage that comes with it What it takes for it to pay off
Selective scaling More instances to operate; need for an orchestrator and load balancing. Parts of the system with genuinely different load demands.
Independent, frequent deployments Contracts between services that must be versioned and not broken; more pipelines. Solid CI/CD and backward-compatibility discipline.
Team autonomy Need for common standards so the whole is operable; risk of duplicated effort. Teams organized by business capability with end-to-end responsibility.
Technological heterogeneity More technologies to master, maintain and secure; harder mobility between teams. Use it judiciously, not on a whim; in many cases a common stack is preferable.
Fault isolation Fault tolerance has to be designed explicitly (timeouts, circuit breakers, degradation). Observability and resilience patterns (module 6).
Small, maintainable codebases Complexity does not disappear: it moves to the interactions between services. Clear contracts and documented dependencies.
(cross-cutting) Network latency, eventual consistency, distributed debugging, infrastructure cost, risk of a distributed monolith. Accepting that you are building a distributed system and training the team for it.

If you look closely, the right-hand column largely describes the content of the rest of the course. Modules 3 through 7 exist to pay, in an orderly way, the costs in the middle column.

Common Mistakes and Tips

  • Counting only the advantages. This is the most frequent mistake in presentations to management: speed and scaling are promised, and the cost of operating fifteen services is left unsaid. Then reality sends the bill. Always present the full table.
  • Believing that fault isolation is automatic. Separating processes does not stop a downed service from dragging down the ones that depend on it if they wait indefinitely for its response. It has to be designed.
  • Underestimating eventual consistency. "The data will sync in a few seconds" sounds harmless until a customer sees their order paid and their stock not reserved. Every flow has to be thought through with that possibility in mind.
  • Adopting technological heterogeneity without need. Being able to use one language per service does not mean you should. Every technology you add is a permanent cost.
  • Forgetting the eight fallacies. Every time you write a call between services, run through them mentally: what if it does not answer? What if it takes 10 seconds? What if it arrives twice?
  • Tip: when someone proposes "pulling X out into a microservice", ask them to name which concrete advantage from the list they are after and which concrete cost they accept. If they cannot name both, the proposal is not mature.

Exercises

Exercise 1: Identifying advantages and costs at TechCorp

For each situation, state which advantage of microservices would help solve it and which disadvantage or cost would have to be accepted in return.

  1. During the January sales campaign, the whole store slows down because thousands of users browse the catalog, even though few of them buy.
  2. The Notifications team wants to try a new SMS delivery provider, but is afraid to touch the monolith because any failure affects sales.
  3. A Friday deployment introduced a bug in payments and the whole application had to be rolled back, including catalog improvements that were working fine.

Exercise 2: Fallacies in action

Read this fragment (simplified, in pseudocode) of how a TechCorp developer might implement order creation by calling other services, and identify at least three fallacies of distributed computing it ignores.

// Illustrative pseudocode, NOT the course implementation
async function createOrder(order) {
  await fetch('http://10.0.0.5:3006/reservations', { method: 'POST', body: JSON.stringify(order) });
  await fetch('http://10.0.0.6:3003/charges',      { method: 'POST', body: JSON.stringify(order) });
  await fetch('http://10.0.0.7:3005/emails',       { method: 'POST', body: JSON.stringify(order) });
  return { status: 'CONFIRMED' };
}

Exercise 3: Making the case to management

Marta has to decide whether TechCorp starts the transition to microservices. Write, in five or six lines, a balanced paragraph presenting her with two advantages and two costs that are concrete for TechCorp, using real situations from the store.

Solutions

Exercise 1

  1. Advantage: selective scaling (replicate only catalog-service). Cost: operating more instances, needing an orchestrator and load balancing; and accepting that the catalog, being a separate service, is queried over the network from orders (latency).
  2. Advantage: fault isolation and independent deployment (trying the new provider in notifications-service without putting sales at risk), plus technological heterogeneity if the provider requires a different library. Cost: you have to design what happens in orders if notifications fails, and maintain a dedicated pipeline and monitoring for that service.
  3. Advantage: independent deployments (roll back only payments-service). Cost: versioned contracts between orders and payments so that rolling back one does not break the other; more deployment pipelines.

Exercise 2

  • The network is reliable: there is no error handling; if any fetch fails, the function throws and the state is left inconsistent (for example, stock reserved with no charge).
  • Latency is zero: three chained synchronous calls; the total time is the sum, and there is no maximum wait time.
  • Topology does not change: the IP addresses are hard-coded; as soon as an instance moves, everything fails.
  • The network is secure: plain HTTP with no encryption or authentication between services.
  • On top of that, it returns CONFIRMED without checking the responses, and if the client retries, stock is reserved and the customer is charged twice (missing idempotency, a consequence of fallacy 1).

Exercise 3 (one possible wording)

Splitting the store into services would let us, on the one hand, scale only the catalog during campaigns such as Black Friday instead of replicating the whole application, and on the other, let the Orders team deploy its fixes as soon as they are ready without waiting for the weekly deployment or putting the rest of the store at risk. In exchange, we would have to accept two clear costs: creating an order would come to depend on network calls to inventory and payments, with the latency and failures that implies and without a single transaction to undo everything if something goes wrong; and we would need to invest in infrastructure and know-how we do not have today (orchestration, messaging, observability) to operate six services instead of one.

Conclusion

In this lesson we saw that microservices offer real advantages (selective scaling, independent deployments, team autonomy, technological freedom, fault isolation and manageable codebases), but that each one comes with an equally real cost: the complexity of a distributed system, network latency and failures, the loss of global transactions, harder testing and debugging, operational cost, organizational demands, and the risk of ending up with a distributed monolith. The eight fallacies of distributed computing sum up why those costs are unavoidable: the network is not reliable, not instantaneous, not secure and not static. The advantage-versus-cost table should accompany you in any architecture discussion.

With both sides of the coin clear, in the next lesson we will make a structured, dimension-by-dimension comparison between the microservices architecture and the monolithic one, and we will follow the same functional change at TechCorp through both to see the differences in practice.

Microservices Course

Module 1: Introduction to Microservices

Module 2: Microservice Design

Module 3: Communication between Microservices

Module 4: Implementing Microservices

Module 5: Deployment and Orchestration

Module 6: Monitoring and Maintenance

Module 7: Security in Microservices

Module 8: Case Studies and Practical Examples

© Copyright 2026. All rights reserved