Communication Patterns
Communication patterns define how services and components interact in a distributed system. The choice decides whether a caller waits, how many parties receive a message, and whether a message can be read again later.
Four Communication Patterns
Request-response, scatter-gather, publish-subscribe, and event streaming.
Request-Response
A client sends a request and waits for the response before continuing.
Use when:
- The caller needs an immediate answer to proceed
- The operation requires confirmation before the next step
- The interaction is a read or a simple create, update, or delete
- A user interface needs real-time feedback
Example: An authentication service where a login request must return success or failure immediately, because the user can’t proceed without it.
Trade-offs: Simple to implement and reason about, but the caller is coupled to the callee’s availability and speed. Every synchronous call needs a timeout, and a chain of synchronous calls can turn one slow or failed service into a cascade.
Scatter-Gather
Pattern from Enterprise Integration Patterns by Gregor Hohpe and Bobby Woolf (2003)
A request fans out to several services in parallel, and their responses are aggregated into a single result.
Use when:
- One answer needs data held by several services
- The services can be queried independently and in parallel
- A partial result is acceptable when some services don’t respond
Key Considerations
- Overall response time is set by the slowest service, unless the aggregator stops waiting at a deadline
- Partial failures need a deliberate policy, such as returning what arrived or failing the whole request
- Results may need merging, ranking, or deduplication
Example: A travel search that queries several airline, hotel, and car rental providers at once and combines what comes back into one set of results.
Publish-Subscribe
A publisher sends a message to a topic without knowing who will receive it, and each subscriber receives its own copy without knowing who sent it.
Use when:
- Several services need to react to the same occurrence
- Publishers shouldn’t depend on who reacts
- Reactions can happen asynchronously
- Each consumer should scale independently
Fan-out and competing consumers: A topic delivers a copy of each message to every subscription, so inventory, payment, and notification services each receive the “order placed” message. Within a single subscription, several instances of the same service can share the work as competing consumers, where each message goes to only one instance. Fan-out decides which services hear about a message. Competing consumers decide how one service scales its processing.
Fan-Out and Competing Consumers
Every subscription gets a copy; one instance per subscription takes it.
Example: Placing an order publishes an “order placed” message, and the inventory, payment, shipping, and notification services each receive it and react independently.
Trade-offs: The publisher is decoupled from its subscribers, which is the point, but it also gets no confirmation that anything acted on the message. A failure surfaces in a subscriber rather than in the caller, so tracing one business operation means following it across several services. Brokers generally deliver at least once, so subscribers have to tolerate the same message arriving twice.
Event Streaming
A stream is a durable, ordered log of events. Consumers read from it at their own position, and events stay in the log after they are read, so consumers can read them again.
Use when:
- Events must be processed continuously and in near real-time
- History matters, and consumers may need to replay past events
- Several consumers read the same events at different rates
- The system uses event sourcing or builds analytics from events
What Makes a Stream Different
Ordering: Events keep their order within a partition, though not necessarily across partitions
Replay: A consumer can reprocess events from an earlier position
Independent consumers: Each consumer tracks its own position in the log
Retention: Events are kept for a configured period, or indefinitely
Publish-Subscribe Messaging
- A message is typically removed once each subscriber has received it
- Consumers that join later usually don't see earlier messages
- Replay generally isn't available
- Simpler to operate
Event Streaming
- Events are retained for a configured period
- New consumers can start from the beginning of retained history
- Consumers can replay from an earlier position
- More capable, and more to operate
Example: A trading platform streams price changes continuously, and a display service, a trading engine, and an analytics service each read the same stream at their own position.
Common implementations: Apache Kafka, Amazon Kinesis Data Streams, Apache Pulsar, Azure Event Hubs
Quick Reference
| Pattern | Timing | Coupling | Receivers | Use case |
|---|---|---|---|---|
| Request-Response | Synchronous | High | One | Immediate answer required |
| Scatter-Gather | Synchronous, parallel | Medium | Several, results combined | One answer assembled from several services |
| Publish-Subscribe | Asynchronous | Low | Every subscriber gets a copy | Several services react to the same occurrence |
| Event Streaming | Asynchronous | Low | Every consumer, at its own position | Continuous processing, history, and replay |
Found this guide helpful? Share it with your team:
Share on LinkedIn