Synchronous vs Asynchronous Communication
Synchronous: the caller blocks waiting for a response (HTTP, gRPC). Asynchronous: the caller publishes a message and continues; the receiver processes it independently (Kafka, SQS, AMQP).
Sync = a phone call (both parties must be on the line at the same time). Async = a voicemail (leave your message, they'll get to it when they can).
Sync communication is simpler to reason about (request-response semantics, easy error propagation) but creates temporal coupling — both services must be up and performant simultaneously. A slow downstream service degrades the upstream caller. Async communication eliminates temporal coupling and enables natural load leveling via buffering, but introduces eventual consistency, message ordering challenges, and requires consumers to be idempotent. Use sync for: queries requiring real-time responses, user-facing reads. Use async for: cross-bounded-context writes, workflows where the caller does not need the result immediately.
Sync call chains create latency amplification: a chain of 5 services each adding 20ms = 100ms minimum latency, before any business logic. More critically, availability compounds multiplicatively: if each service is 99.9% available, a 5-service chain is 99.5% available. This is why sync microservice 'orchestration via HTTP' is an anti-pattern for complex workflows. The request-reply pattern over async messaging (a reply-to queue with a correlation ID) allows async communication while preserving a request-response programming model, useful during migrations from sync to async.
My decision rule: if the caller needs the result of the operation to proceed (e.g., 'is this payment authorized?'), use sync. If the caller needs only to record the intent of an operation (e.g., 'send a shipping notification'), use async. For multi-step workflows I always use async + saga rather than sync chaining, because the availability math makes sync chaining at scale unreliable.
Building a synchronous RPC mesh between microservices and calling it microservices architecture. If every service call is synchronous HTTP, you have a distributed monolith with all of the complexity of distribution and none of the resilience benefits.