Microservices Service Communication

Let’s say you’ve split your app into microservices. A microservice is just one small service that does one job, like handling orders or processing payments. So far so good. But now you’ve got a problem:

  • A customer places an order, so your Orders service kicks in.
  • But to actually finish that order, it needs the Payments service to charge the card.
  • These two are separate programs, maybe even running on different machines.

So how do they talk to each other? They can’t just call a function across the room, right? They have to send messages over the network. And there’s more than one way to do that. Picking the right way is one of the most important decisions in microservices, and it’s a classic interview topic too.

Let’s break it down.

🎯 The Core Choice

When one service needs something from another, there are two broad ways to do it. Everything else is a detail on top of these two.

  • Synchronous means call and wait. The Orders service calls Payments and just sits there, waiting for the reply, before it does anything else. Like calling a friend and staying on the line until they answer your question.
  • Asynchronous means send and move on. The Orders service drops off a message saying “an order was placed” and immediately gets back to work. Payments picks that message up and handles it whenever it’s ready. Like texting a friend and going about your day, knowing they’ll read it soon.

That’s the whole core choice. Now let’s look at each one properly.

🔁 Synchronous Communication

Synchronous communication means the caller waits for a reply before moving on. Here’s how it plays out:

  • The Orders service sends a request to Payments: “charge this card for 50 dollars.”
  • Then it stops and waits. It does nothing else until Payments answers.
  • Payments charges the card and sends back a reply: “done, payment successful.”
  • Only now does Orders continue, marking the order as paid.

The two most common ways to do synchronous calls are REST and gRPC:

  • REST over HTTP is the everyday way services talk. REST is just a style of sending requests over HTTP using simple URLs and methods like GET and POST. It’s the same HTTP your browser uses, so it’s familiar and works everywhere.
  • gRPC is a faster, more structured option. gRPC is a framework where services agree on an exact message format ahead of time and send compact binary data instead of plain text, which makes it quick and well suited for service-to-service calls inside your system.

Here’s the key thing to picture. In a synchronous call, the caller is blocked while it waits. Blocked just means it’s stuck holding, unable to do other work until the answer comes back.

charge card, please

payment successful

Orders service

Payments service

Waits for reply, then continues

📨 Asynchronous Communication

Asynchronous communication means the caller sends a message or an event and does not wait for a reply. It fires off the message and gets right back to work. Here’s the flow:

  • The Orders service publishes an event: “OrderPlaced.” Publishing just means dropping the message into a shared place for others to pick up.
  • It does not wait. It moves on immediately, maybe telling the customer “order received.”
  • That message sits in a message queue or an event bus until someone reads it. A message queue is a holding area where messages line up safely until a service is ready to handle them. An event bus is similar, a channel where one service announces something and any interested service can react.
  • The Payments service reads the “OrderPlaced” event later and charges the card on its own time.

So the sender and the receiver are not locked together. To go deeper on the holding area in the middle, see the Message Queues lesson.

publish: OrderPlaced

delivers later

Orders service

Message queue / event bus

Moves on right away

Payments service reacts

Why async feels slower but scales better

With async, the work still gets done, just not this exact instant. The Orders service doesn’t sit around waiting, so it can handle way more requests. The trade-off is that you give up the instant “yes it worked” reply, since the real work happens a moment later in the background.

⚖️ Synchronous vs Asynchronous

Here’s the side-by-side so you can see the trade-offs at a glance.

Aspect Synchronous (call and wait) Asynchronous (send and move on)
Does the caller wait? Yes, it blocks until the reply comes No, it moves on immediately
Reply Gets an answer right away No instant reply, handled later
Coupling Tighter, both must be up at once Looser, receiver can be busy or down
Common tools REST over HTTP, gRPC Message queues, event bus
Best for Immediate request and response Background work, spikes, fan-out
Risk One slow service slows everyone Harder to track and debug the flow

✅ When to Use Each

Neither one is “better.” You pick based on what the job actually needs.

Reach for synchronous when you need an answer right now:

  • A user is logging in and you need to check the password before letting them in.
  • The checkout page needs to know “is this item in stock?” before showing the button.
  • Anytime the next step truly can’t continue without the reply, you want call-and-wait.

Reach for asynchronous when you want services to be independent:

  • Decoupling. Decoupling means services don’t depend on each other being up at the same moment. If Payments is busy, Orders still works.
  • Background work. Sending a confirmation email or generating a report can happen later, so don’t make the user wait for it.
  • Handling spikes. When traffic suddenly jumps, the queue holds the extra messages and services drain them steadily instead of crashing.
  • Fan-out. Fan-out is when one event needs to reach many services at once. One “OrderPlaced” event can wake up Payments, Inventory, and Email all together.

⚠️ The Risks of Sync Calls

Synchronous calls feel simple, and they are. But they have a sharp edge you need to know about.

  • When services call each other synchronously in a long line, they become tightly coupled. Tightly coupled means each one depends on the next being fast and healthy. Orders waits on Payments, which waits on Fraud-check, which waits on the Bank.
  • If any one service in that chain gets slow, everyone before it is stuck waiting too. The slowness travels backward up the whole line.
  • Worse, if one service goes down, the failure can ripple back and take down the others with it. That ripple has a name, a cascading failure, where one broken service drags down everything that was waiting on it.

slowness ripples back

Orders waits

Payments waits

Fraud check waits

Bank is slow or down

The usual guard against this is the circuit breaker, which stops calling a service that’s clearly broken so the failure doesn’t spread. See the Circuit Breaker Pattern for how that works.

🧩 REST vs gRPC

Both REST and gRPC are synchronous, so when you’ve decided to call-and-wait, this is the next choice. Here’s the short version:

  • REST is simple and universal. It rides on plain HTTP, sends human-readable data like JSON, and works with basically every language and tool out there. It’s the easy default, especially for APIs that outside developers or browsers will call.
  • gRPC is fast and typed. Typed means the exact shape of every message is agreed on in advance, so mistakes get caught early. It sends compact binary data, which is quicker than text, making it a great fit for internal service-to-service calls where speed matters and humans aren’t reading the messages.

A simple rule of thumb: REST for public-facing or simple APIs, gRPC for chatty internal traffic between your own services.

⚠️ Common Mistakes and Misconceptions

A few ideas trip people up here. Let’s clear them out:

  • “Everything must be synchronous.” No. People default to call-and-wait because it’s familiar, but a lot of work, like emails, reports, and notifications, doesn’t need an instant reply and is better off async.
  • “Async is always better.” Also no. Async adds real complexity. Now you’ve got queues to run, messages that might arrive twice, and flows that are harder to trace. For a simple “give me an answer now” need, plain REST is the right call.
  • “Long chains of sync calls are fine.” They’re not. The more services you string together in a waiting line, the more fragile the whole thing gets. One slow link slows everyone, and one failure can cascade. Keep sync chains short, or break them up with async.

🛠️ Design Challenge

Try this on your own to test yourself.

Imagine an e-commerce checkout. When Alex clicks “Place Order,” a few things need to happen: charge the card, reserve the item from inventory, send a confirmation email, and update the recommendations engine. For each of those, decide whether it should be synchronous or asynchronous, and write down why. For example:

  • Charging the card probably needs to be synchronous, since you can’t confirm the order without knowing the payment went through.
  • Sending the email can be asynchronous, since nobody needs to wait at the screen for it.

Work through all four. This is exactly the kind of trade-off reasoning interviewers love to see.

🧩 What You’ve Learned

You can now explain how microservices talk to each other. Here’s what you’ve picked up.

  • ✅ Synchronous communication is call-and-wait, done with REST over HTTP or gRPC.
  • ✅ Asynchronous communication is send-and-move-on, done with message queues or an event bus.
  • ✅ Use sync when you need an immediate request and response.
  • ✅ Use async for decoupling, background work, traffic spikes, and fan-out.
  • ✅ Long chains of synchronous calls cause tight coupling and risk cascading failures.
  • ✅ REST is simple and universal, gRPC is fast and typed for internal traffic.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    What does synchronous communication mean between two services?

    Why: Synchronous means call-and-wait: the caller blocks until it gets the reply, as with REST or gRPC.

  2. 2

    Which situation is a good fit for asynchronous communication?

    Why: Sending an email can happen later in the background, so the user does not need to wait for it.

  3. 3

    Why are long chains of synchronous calls risky?

    Why: Tightly coupled sync chains let slowness or failure ripple backward, which can cause a cascading failure.

  4. 4

    When would you usually pick gRPC over REST?

    Why: gRPC is typed and sends compact binary data, which suits fast internal traffic between your own services.

🚀 What’s Next?

You’ve got the two core ways services communicate. Next, go deeper into the patterns that build on them.

Once you’ve got those, you’ll be able to design service communication that stays fast and survives failures at scale.

Share & Connect