← experimental
Contents
  1. The Core Distinction
  2. Trade-off Table
  3. When Synchronous Is Right
  4. When Asynchronous Is Right
  5. Availability Chaining: The Key Risk of Synchronous Chains
  6. Async Concerns to Address Explicitly
  7. The Mixed Model: Sync Outside, Async Inside
  8. Decision Guide
  9. Related Concepts

The Core Distinction

This is fundamentally a coupling decision, not an implementation one. The question "should I call this synchronously or asynchronously?" is a special case of the question "how much temporal coupling am I willing to accept?"

Synchronous: the caller blocks until the callee responds. Both parties must be simultaneously available. The caller's progress depends directly on the callee's availability and performance.

Asynchronous: the caller sends a message and continues. The callee processes when it is ready. The parties are temporally decoupled — neither requires the other to be available at the same moment.

Newman (→ Monolith To Microservices) identifies temporal coupling as one of the four fundamental coupling types: service A can only function when service B is simultaneously available. Synchronous calls are the primary cause of temporal coupling in distributed systems.

Trade-off Table

Dimension Synchronous Asynchronous
Temporal coupling High — caller blocked; callee must be up None — message persists until delivery
Availability chaining Yes — callee slowness cascades to caller No — channel buffers demand
Simplicity High — familiar request/reply; easy to trace Low — requires correlation IDs, ordering awareness
Latency (p50) Lower — no queueing overhead Higher — message must be queued and delivered
Latency (tail) High — slow callee = slow caller Bounded — queue absorbs spikes
Result delivery Immediate — caller has result when it proceeds Deferred — caller receives result via callback or polling
Idempotency requirement Situational (retries possible) Essential — at-least-once delivery requires idempotent consumers
Observability Simpler — linear call stack Harder — requires distributed tracing; correlation IDs mandatory
Failure isolation Poor — callee outage blocks caller Good — caller continues; messages queue
Transaction boundary Can span a single ACID transaction across the call Requires eventual consistency or saga patterns

When Synchronous Is Right

The caller genuinely needs the result before it can proceed. A credit-card authorisation must complete before an order is confirmed. A search query must return results before a page can render. When the caller's next action depends logically on the callee's response, synchronous is the natural model.

User-facing operations expecting an immediate response. North-south traffic (browser/mobile → backend) is almost always synchronous: the user is waiting. The acceptable latency budget is short (< 1–2 seconds), which also caps how many synchronous hops the request can make before hitting that budget.

The operation is read-only and idempotent. Synchronous reads have no retry amplification risk and no ordering concerns.

The simplicity benefit outweighs the coupling cost. When both services are on the same team, co-deployed, and tightly related, temporal coupling may be an acceptable trade-off for simpler code.

Practical requirement: every synchronous call must have a timeout. Without a timeout, a slow or unresponsive callee can hold the caller's thread indefinitely — a resource leak that causes cascading failures (→ Timeout). Nygard's rule: slow responses are worse than refused connections, because refused connections fail fast while slow responses drain the caller's capacity.

When Asynchronous Is Right

Background and long-running processing. Order fulfilment, report generation, email delivery, video encoding — none of these need the caller to wait. Queue the work; the caller confirms receipt, not completion.

Event fan-out. One producer event needs to reach multiple independent consumers. Async pub/sub avoids tight coupling between producer and each consumer; new consumers can be added without touching the producer (→ Event Driven Architecture).

Cross-bounded-context integration. When two services belong to different bounded contexts with different ownership and deployment lifecycles, synchronous coupling merges their operational fate. Async messaging is the default for cross-context data sharing: each team publishes events; consumers read independently (→ Building Event Driven Microservices ch. 1).

Absorbing demand spikes. A message queue naturally levels load: producers send at peak rate; consumers process at their own pace. Synchronous chains amplify throughput pressure upstream.

Resilience over simplicity. If the callee is known to be unreliable or slow, async with retry is more robust than sync with timeout and fallback. The Retry pattern is most naturally expressed as a queue consumer that retries on failure.

East-west service communication. Between internal services (east-west), async messaging is often the preferred default: it eliminates temporal coupling, enabling services to be deployed, scaled, and failed independently.

Availability Chaining: The Key Risk of Synchronous Chains

In a synchronous call chain A → B → C, the availability of A is the product of the availability of all three services. If each service is 99.9% available:

Chain availability ≈ 0.999 × 0.999 × 0.999 ≈ 99.7%

Each additional synchronous hop multiplies the downtime. A five-hop synchronous call chain among 99.9%-available services yields only ~99.5% availability — without any other failure mode. This effect is why the SATH dynamic coupling model (→ Software Architecture The Hard Parts) identifies communication (sync vs async) as one of the three primary axes of distributed workflow complexity, alongside consistency and coordination.

Async messaging breaks the chain: the producer's availability is decoupled from the consumer's. The broker absorbs the gap.

Async Concerns to Address Explicitly

Choosing async is not free. These concerns must be handled:

Idempotency: at-least-once delivery is the reliable delivery guarantee for most messaging systems. Consumers must handle duplicate messages without double-processing. Idempotency keys are the standard mechanism (→ Idempotency).

Ordering: messages within a partition/topic are ordered; messages across partitions are not. Systems that depend on ordering (e.g., state machine transitions) must either constrain to a single partition or implement sequence numbers and out-of-order buffering.

Correlation: when a caller sends a message and later receives a response, it must be able to match the response to the original request. Correlation identifiers are the standard mechanism (→ Messaging).

Backpressure: a slow consumer facing a fast producer accumulates an unbounded queue. Monitoring queue depth and applying backpressure or scaling consumers is an operational requirement. See Backpressure for the mechanisms (bounded queues, credit-based flow control, pull-based consumption) and Queueing Theory for why unbounded queues produce unbounded latency.

Distributed tracing: async message flows are invisible to traditional call-stack profilers. Trace IDs must be propagated through message headers; a distributed tracing system (Jaeger, Zipkin) is necessary to reconstruct flows (→ Observability).

The Mixed Model: Sync Outside, Async Inside

The most common pattern in mature distributed systems:

  • North-south (user → backend): synchronous — the user waits for a response
  • East-west (service → service): asynchronous — services decouple via events or queues
  • Backend for Frontend (BFF): a synchronous surface aggregating from async internal services — the BFF calls downstream synchronously where needed and reassembles the async result

This is not a contradiction: the synchronous user-facing call completes quickly because the backend processes asynchronously and returns a receipt ("order accepted; you'll be notified"). The user gets immediate feedback; the internal processing is decoupled.

For Bellemare (→ Building Event Driven Microservices), the default for event-driven microservices is fully async east-west communication via event streams, with synchronous APIs reserved for user-facing queries.

Decision Guide

Situation Default choice
User waits for the result (UI, API consumer) Synchronous
Caller must have the result to proceed (auth, pricing) Synchronous
Background work; caller doesn't need the result immediately Asynchronous
Processing must survive callee downtime Asynchronous
Cross-team, cross-bounded-context integration Asynchronous
One event → multiple independent consumers Asynchronous (pub/sub)
East-west between independently-deployed services Asynchronous
Long-running operations (>2s) Asynchronous
High-throughput with variable load Asynchronous
Simple, co-owned internal services Either (synchronous simpler)
  • Coupling — temporal coupling is Newman's term for the availability dependency created by synchronous calls
  • Integration Styles — EIP's four styles: File Transfer and Messaging are async; RPI is synchronous; Shared Database is neither
  • Messaging — the implementation vocabulary for async: channels, delivery guarantees, correlation, backpressure
  • Backpressure — flow control as the architectural answer to producer/consumer rate mismatch
  • Queueing Theory — Little's Law, utilisation curves, and tail latency in async pipelines
  • Stability Patterns — Decoupling Middleware as one of Nygard's stability decisions
  • Event Driven Architecture — async communication as the structural default for event-driven systems
  • Saga — the distributed transaction pattern for sequences of async operations; choreography vs orchestration
  • Timeout — the required companion to every synchronous call; without it, async failure modes appear in sync code
  • Retry — transient failure recovery; more naturally expressed as async queue re-delivery than sync retry loops
  • Idempotency — prerequisite for safe async at-least-once delivery
  • Observability — async flows require distributed tracing; correlation IDs are mandatory
  • Orchestration Vs Choreography — once you choose async, you must choose how to coordinate the resulting event flows