skip to content

Inter-Service Communication

Choosing between REST, gRPC and messaging for each interaction, and between request/reply and publish-subscribe. You will weigh choreography against orchestration and learn why synchronous chains quietly multiply latency and failure probability.

part ofMicroservices architectureoverview, primer and where to startread it →
on this pageshow

questions

6

In a microservices system, what's the basic difference between a synchronous call between services (like REST over HTTP) and an asynchronous message (like publishing to a queue), and when would you pick each?

level: juniorimportance: must knowfreq 85%

answer

  1. phone call vs voicemail
  2. temporal coupling
  3. queue depth vs timeout
  4. immediate answer needed?

basics

~20 s

A synchronous call waits for an immediate answer before moving on, like a phone call. An asynchronous message is sent off while the sender keeps working, like leaving a voicemail; the other side handles it and replies whenever it's ready.

solid answer

~50 s

In synchronous communication (REST or gRPC over HTTP), the caller opens a connection, sends a request, and blocks until it gets a response or hits a timeout, so it needs the callee reachable and fast right now. In asynchronous communication, the caller publishes a message to a queue or topic and immediately continues; the receiver processes it independently, maybe seconds or hours later, with no live connection held open. Pick synchronous when the caller genuinely cannot proceed without the answer, such as checking card validity before rendering a confirmation page, and low latency matters more than decoupling. Pick asynchronous when the caller doesn't need an immediate result, when the receiver could be temporarily unavailable, or when you want the services' uptime and scaling to be independent of each other, such as notifying several downstream services that an order was placed.

go deeper

for a junior

Should correctly identify that sync blocks for a response and async doesn't, and give one plausible example of each without conflating 'async' with 'fast' or 'sync' with 'slow'.

for a middle

Should articulate the decoupling benefit of async (receiver can be down temporarily) and the immediacy requirement that justifies sync, and pick correctly between them for a stated scenario.

for a senior

Should discuss temporal coupling, cascading failure risk in sync chains, and the operational cost of async (queue depth monitoring, redelivery, idempotency) as concrete trade-offs, not just abstract pros/cons.

for a principal

Should reason about mixing both patterns deliberately within one workflow, and talk about how the choice affects organizational boundaries, on-call ownership, and failure blast radius across teams, not just the technical mechanics.

## The question every call answers Every call between two microservices answers one question first: **does the caller need the result before it can keep doing its own work?** That question splits inter-service communication into two families. - **Synchronous communication**, typically `REST` over HTTP or `gRPC`, opens a connection, sends a request, and the caller's thread or async handler waits for a response, succeeding, failing, or timing out. - **Asynchronous communication** instead has the caller hand a message to an intermediary, most often a queue or topic, and return immediately; the receiving service picks the message up on its own schedule and does the work, with no open connection linking the two at that moment. ## Why both styles exist The reason both styles exist is that they optimize for different things. **Synchronous calls** exist because some workflows are inherently request-response: a checkout page cannot render a confirmation until it knows whether the payment authorized, so the caller needs the answer in hand before it can produce its own output. This buys two things: - **Simplicity of reasoning** — the code reads top to bottom like a normal function call. - **Freshness** — the caller always gets a current answer rather than a stale cached one. **Asynchronous messaging** exists to decouple two services in time and in availability: the publisher does not care whether the consumer is up, overloaded, or mid-deployment right now, because the message will simply wait in the queue until a consumer is ready. This buys two things: - **Resilience** to partial outages. - **The ability to smooth out load spikes** — a burst of incoming work becomes a growing queue depth rather than a wave of failed requests. ## Costs on the other side The trade-offs cut the other way too. **Synchronous calls create temporal coupling.** If the callee is slow or down, the caller is stuck waiting or failing right along with it, and a chain of three or four synchronous calls multiplies the chance that at least one link is unhealthy at any given moment. They also tie the caller's capacity to the callee's capacity in real time, so a burst of traffic that a downstream service cannot absorb turns into a wall of timeouts for everyone upstream of it. **Asynchronous messaging trades that immediacy for eventual consistency.** The caller cannot know, at the moment it publishes, whether or when the work will complete, so any workflow that needs a same-request answer has to be redesigned around polling, callbacks, or a separate synchronous read. It also adds new machinery to operate and reason about: a broker, delivery guarantees, ordering guarantees, and often idempotency handling on the consumer side, because most brokers can redeliver a message. ## How each one breaks In production: | Style | How trouble shows up | |---|---| | **Synchronous** | Chains fail loudly and immediately, which is easy to see but easy to cascade: a slow database behind service C shows up as a growing thread pool and rising latency in service B, and then in service A, and eventually the whole request path times out even though only one node was actually unhealthy. | | **Asynchronous** | Systems fail more quietly: a consumer that silently stops processing does not throw an error at the publisher, it just lets the queue back up, and the first sign of trouble is often a growing backlog or a business-side complaint that "orders placed an hour ago still say pending," not a stack trace. | That is why asynchronous systems need their own observability, specifically queue depth and consumer lag dashboards, rather than relying on the caller noticing an error. ## Both styles in one checkout A concrete example — an e-commerce checkout typically uses: 1. A **synchronous** call from the order service to the payment service, because the customer is staring at a spinner and the page cannot proceed without an authorization result. 2. **Asynchronous** messaging, in the same checkout flow, to tell the inventory, shipping, loyalty-points, and analytics services that an order was placed, because none of those need to hold up the checkout page and the order service should not have to know or care whether all four of them are currently healthy. Mixing the two deliberately — synchronous on the critical path where an immediate answer is required, asynchronous everywhere the caller can move on without one — is the normal shape of a well-designed service boundary rather than an either-or architectural choice made once for the whole system.

  • If synchronous calls create temporal coupling and cascading risk, why not make every inter-service call asynchronous?
    Because plenty of workflows genuinely need an answer before they can produce their own output, like authorizing a payment before showing a confirmation page, and forcing those into async messaging just means reinventing request-response on top of a queue with polling or callbacks, which adds latency and complexity without removing the underlying need. Async also introduces eventual consistency and redelivery concerns that a simple read-then-respond flow doesn't need.
  • How would you notice in production that a synchronous call chain is starting to cascade?
    Rising p99 latency and thread-pool or connection-pool saturation in the caller that correlates with slowness in a downstream dependency, often visible as the same timeout pattern climbing up multiple services in a distributed trace. Circuit breaker trip counts and a spike in 5xx or timeout errors at the edge are usually the first alerting signal.
  • What's a case where you might use both patterns for the same piece of information?
    A service might synchronously query another for the current, authoritative state (like current inventory count before confirming an order) while also asynchronously consuming an event stream to keep a local cache warm for fast reads, falling back to the synchronous call only when the cache is stale or missing.

Synchronous is calling someone on the phone and waiting on hold until they pick up and answer you; asynchronous is texting them and going about your day, trusting they'll reply when they get to it.

saying these in an interview costs you the question

  • Says async is 'always better' or 'always slower' without naming the trade-off it's optimizing for
  • Can't explain why a caller would ever need to block on a response
  • Thinks a message queue guarantees the message is processed instantly
  • Assumes synchronous calls can't fail partially or cascade
  • Doesn't mention that async requires the consumer to handle work independently of when it was published

context

open as a page

What's the difference between the request/reply and publish/subscribe messaging patterns for service-to-service communication, and what coupling trade-off does each impose?

level: middleimportance: must knowfreq 80%

basics

~20 s

Request/reply is one service asking another a direct question and getting a direct answer, like calling a specific person. Publish/subscribe is one service announcing something happened, and any number of other services that care can listen in, like posting an announcement on a notice board.

open as a page

In an order-fulfillment flow spanning an Order, Payment, Inventory, and Shipping service, what's the difference between choreography (each service reacts to events from the others) and orchestration (a central coordinator directs each step), and what are the concrete trade-offs?

level: seniorimportance: must knowfreq 75%

basics

~20 s

Choreography is like a dance where everyone reacts to what everyone else does, with no one in charge. Orchestration is like a conductor telling each musician exactly when to play. Choreography has no single controller; orchestration has one service driving the whole process.

open as a page

A team is choosing between REST with JSON over HTTP/1.1 and gRPC over HTTP/2 for synchronous calls between two internal services. What concrete technical trade-offs should drive that decision?

level: middleimportance: should knowfreq 65%

basics

~20 s

REST with JSON is simple, human-readable, and works everywhere, including browsers, but is slower to parse and less strict about structure. gRPC uses a compact binary format and a strict contract, making it faster and safer between services, but harder to read by hand and not natively usable from a browser.

open as a page

Service A calls Service B synchronously over REST, and B in turn calls Service C synchronously. C starts responding slowly under load. What failure mode does this create for A, and what are the standard mitigations?

level: seniorimportance: should knowfreq 70%

basics

~20 s

C being slow makes B slow, which makes A slow too, and if nothing stops it, all three can eventually run out of capacity and fail together, like one traffic jam backing up onto every road behind it. Fixes include setting time limits, giving up early instead of piling up more requests, and having a backup plan when the answer doesn't come.

open as a page

You're designing the communication for a saga spanning five services with compensating actions on failure. Under what conditions would you choose choreography versus orchestration, and what does each cost you in observability and evolvability as the system grows?

level: principalimportance: nice to knowfreq 40%

basics

~20 s

If the steps are simple and mostly independent, letting each service react on its own (choreography) keeps things flexible as you add more services. If the steps are tightly sequenced with real error handling and rollback logic, having one coordinator (orchestration) keeps the whole process understandable as it grows, even though that coordinator becomes something everyone has to touch.

open as a page