Thuan: Hey Alex, can I ask you something? Every job posting I see says “microservices experience required.” But half the projects I’ve worked on… honestly, they didn’t need microservices at all. What’s going on?
Alex: Ha! That’s a great question. Let me answer with a story. Imagine you run a small restaurant. Just you and two cooks. Everything happens in one kitchen. Orders come in, food goes out. Simple, right?
Thuan: Sure. That’s basically a monolith. One application, everything in one place.
Alex: Exactly. And for a small restaurant, that works perfectly. Now imagine you grow. You have 50 cooks, 10 types of cuisine, and thousands of orders per hour. Suddenly, one kitchen doesn’t work anymore. The sushi chef bumps into the pizza guy. Someone spills soup on the dessert station. Everything is connected, and one mistake affects everyone.
Thuan: So you split the kitchen into separate stations?
Alex: Bingo. That’s microservices. Each station — each service — handles one thing. The sushi station doesn’t need to know how pizza works. They just need to know: “When an order comes in for sushi, I make sushi. When it’s done, I put it on the counter.”
Thuan: OK, that makes sense for a big restaurant. But here’s what bugs me. I’ve seen startups with five developers split their app into fifteen microservices. On day one. Before they even have customers.
Alex: And let me guess — they spent more time managing infrastructure than building features?
Thuan: Exactly! They had Kubernetes, service mesh, message queues, distributed tracing… and the product was a simple CRUD app.
Alex: That’s what I call “resume-driven architecture.” They chose the technology because it looks good on LinkedIn, not because the problem required it.
When Does a Monolith Stop Working?
Thuan: So let’s be practical. How do you know when a monolith is actually becoming a problem?
Alex: There are three real signs. First sign: deployment fear. When your team is afraid to deploy because changing one small thing might break something completely unrelated. Like, you update the user profile page and suddenly the payment system crashes.
Thuan: Oh, I’ve lived that. We had a bug where changing a date format in the reporting module broke the login page. They shared a utility function that nobody realized was being used everywhere.
Alex: Classic monolith problem. Everything talks to everything. Second sign: team blocking. When Team A can’t deploy their feature because Team B isn’t finished with theirs, and both teams are working in the same codebase, same deployment pipeline. You’re stepping on each other’s toes.
Thuan: What’s the third sign?
Alex: Scaling mismatch. Imagine your app has a search feature that gets a thousand times more traffic than your admin dashboard. In a monolith, you have to scale the entire application just to handle the search load. That’s like buying a bigger building just because the sushi station needs more space.
Thuan: So with microservices, you can scale just the search service independently?
Alex: Exactly. You give the sushi station its own kitchen. The pizza station stays the same size because it doesn’t need more room.
The Hidden Costs Nobody Talks About
Thuan: OK, so microservices solve real problems. But what do they cost? Because in my experience, the cost is huge.
Alex: Let’s list them out. First, network calls replace function calls. In a monolith, when your order service needs user data, it just calls a function. Takes microseconds. In microservices, that’s an HTTP call or a gRPC call. That takes milliseconds. And it can fail. The network can timeout, the other service can be down.
Thuan: So now you need retry logic, circuit breakers, fallback strategies…
Alex: Second cost: data consistency. In a monolith, you have one database. You can use transactions. “Transfer money from Account A to Account B” — either both happen or neither happens. Simple. In microservices, each service has its own database. Now how do you do a transaction across two services?
Thuan: That’s the saga pattern, right? Where each service does its part and if one fails, the others compensate?
Alex: Exactly. And implementing sagas correctly is genuinely hard. I’ve seen senior engineers get it wrong. You need to handle partial failures, timeouts, out-of-order messages… it’s a whole different world compared to a database transaction.
Thuan: What else?
Alex: Debugging. In a monolith, you get a stack trace. You can follow the code from start to finish. In microservices, a single user request might touch five services. When something goes wrong, you need distributed tracing — tools like Jaeger or Zipkin — to follow the request across services. Without that, debugging is like trying to solve a murder mystery with witnesses in five different cities.
Thuan: I love that analogy. And I’d add one more cost: deployment complexity. Instead of deploying one app, you’re deploying fifteen. Each one needs its own CI/CD pipeline, its own health checks, its own monitoring, its own logs.
Alex: And they all need to be compatible with each other. If Service A expects version 2 of Service B’s API, but Service B just deployed version 3 with breaking changes… boom.
The Decision Framework I Actually Use
Thuan: So how do you decide? Is there a practical framework?
Alex: I use what I call the “two pizza team” test. Not original — Jeff Bezos came up with the name — but I’ve adapted it. Here are my four questions:
Question 1: How big is your team? If you have fewer than ten developers, stay with a monolith. Seriously. The coordination overhead of microservices will eat you alive. One team, one codebase, one deployment. Keep it simple.
Thuan: What about ten to thirty developers?
Alex: That’s the “maybe” zone. Question 2: Are different parts of your app changing at very different speeds? If your payment system is stable and changes once a month, but your recommendation engine changes three times a day, that’s a good candidate for splitting. The recommendation engine becomes its own service with its own deployment cycle.
Thuan: And questions 3 and 4?
Alex: Question 3: Do different parts have different scaling needs? Like our search example earlier. If yes, microservices make sense for those specific parts. Question 4: Do you have the infrastructure maturity? This is the one people skip. Do you have good CI/CD? Do you have monitoring? Do you have container orchestration? If the answer is no, don’t do microservices. Fix your infrastructure first.
Thuan: So basically, your message is: start with a monolith, and extract services when you have a specific pain point?
Alex: Exactly. Martin Fowler calls it the “monolith first” approach. Build a well-structured monolith. Use clean modules. Define clear boundaries between components. When a specific module needs to be independent — because of scaling, deployment speed, or team autonomy — extract it into a service.
Real-World Example: How I’d Split a Monolith
Thuan: Can you walk me through a real example? Like, if we had an e-commerce monolith, how would you split it?
Alex: Sure. Day one, everything is one app. User accounts, product catalog, shopping cart, orders, payments, search, reviews. One database, one deployment.
Now let’s say the business grows. We’re getting ten thousand orders per day. The search feature is slow under load. The recommendation engine needs machine learning, which requires Python, but everything else is in Java. And the payments team wants to deploy independently because they have compliance requirements.
Thuan: So you extract three services: search, recommendations, and payments?
Alex: Exactly. Not fifteen. Three. And everything else stays in the monolith. The product catalog, shopping cart, user accounts, reviews — they don’t need to be separate. They change together, they’re maintained by the same team, and they share a database with straightforward transactions.
Thuan: What about communication between them? How does the monolith talk to the search service?
Alex: For search, I’d use an API call. The monolith sends a search query, the search service returns results. Simple request-response pattern. For payments, I’d use events. When an order is placed, the monolith publishes an “OrderCreated” event. The payment service listens for that event and processes the payment. If it succeeds, it publishes “PaymentCompleted.” If it fails, “PaymentFailed.”
Thuan: Why events for payments but API calls for search?
Alex: Great question. Search is synchronous — the user is waiting for results right now. Payments are asynchronous — the user doesn’t need to stare at the screen while the payment processes. They can see “Payment processing…” and move on. Events are perfect for that because they naturally decouple the services. The monolith doesn’t need to know if the payment service is up or down at that exact moment. The event will be processed when the service is ready.
Key Takeaways You Can Explain to Anyone
Thuan: OK Alex, let’s wrap up. If someone asks me “should we use microservices?” — what do I tell them?
Alex: Tell them this:
-
Start with a monolith. It’s simpler, faster to develop, and easier to debug. Don’t split until you have a reason.
-
A well-structured monolith is better than badly done microservices. Clean modules inside one app beat a spaghetti of services calling each other randomly.
-
Split when you have a specific pain point — scaling, deployment speed, or team autonomy. Not because a conference speaker said so.
-
Each microservice you add is a new thing to deploy, monitor, debug, and secure. Make sure the benefit outweighs that cost.
-
The best architecture is the one your team can actually operate. A beautiful microservices design that your team can’t debug at 3 AM is worse than a boring monolith that everyone understands.
Thuan: That last one is so important. Architecture is not about what’s technically elegant. It’s about what lets your team ship reliably.
Alex: Exactly. Architecture serves the team, not the other way around.
Thuan: Thanks Alex. Coffee’s on me next time.
Alex: Deal. Next time, let’s talk about APIs — REST versus GraphQL versus gRPC. I have opinions.
Thuan: You always have opinions.
This is Part 1 of the Tech Coffee Break series — casual conversations about real tech concepts, designed for listening and learning.
Next up: Part 2 — REST, GraphQL, gRPC — Which One Do I Pick?