Bird
Raised Fist0
Microservicessystem_design~7 mins

Request-response vs event-driven in Microservices - Architecture Trade-offs

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Problem Statement
When services communicate synchronously using request-response, a slow or failing service can block the entire workflow, causing delays or failures. Conversely, without asynchronous communication, systems struggle to handle high loads or complex workflows that require decoupling and resilience.
Solution
Request-response uses direct calls where a service waits for a reply before continuing, ensuring immediate feedback but tight coupling. Event-driven architecture sends messages or events asynchronously, allowing services to react independently and improving scalability and fault tolerance by decoupling components.
Architecture
Service A
Service A
Service B
Service B

The diagram shows two communication styles: synchronous request-response where Service A waits for Service B's reply, and asynchronous event-driven where Service A emits an event to an event bus that Service B consumes independently.

Trade-offs
✓ Pros
Request-response provides immediate feedback and simpler error handling due to synchronous calls.
Event-driven enables loose coupling, improving system scalability and resilience to failures.
Event-driven supports complex workflows and better load distribution by decoupling services.
✗ Cons
Request-response can cause cascading failures and increased latency if downstream services are slow or unavailable.
Event-driven systems add complexity in managing eventual consistency and debugging asynchronous flows.
Event-driven requires infrastructure like message brokers, increasing operational overhead.
Use request-response when immediate response is critical and service dependencies are stable and low-latency. Use event-driven when building scalable, resilient systems with complex workflows or high throughput requirements.
Avoid request-response for high-latency or unreliable downstream services to prevent blocking. Avoid event-driven for simple, low-scale systems where added complexity and infrastructure are not justified.
Real World Examples
Uber
Uses event-driven architecture to decouple services like ride matching and notifications, enabling asynchronous processing and scaling under high demand.
Netflix
Employs request-response for user authentication where immediate validation is required, and event-driven for streaming data processing pipelines.
Amazon
Uses request-response for order placement to ensure immediate confirmation, and event-driven for inventory updates and shipment tracking asynchronously.
Code Example
The before code shows a synchronous HTTP request where Service A waits for Service B's response. The after code demonstrates an event-driven approach where Service A publishes an event to an event bus, and Service B asynchronously processes it without blocking Service A.
Microservices
### Before: Request-Response (Synchronous)
import requests

def get_user_data(user_id):
    response = requests.get(f"http://service-b/users/{user_id}")
    if response.status_code == 200:
        return response.json()
    else:
        return None


### After: Event-Driven (Asynchronous)
import asyncio

class EventBus:
    def __init__(self):
        self.subscribers = []

    def subscribe(self, callback):
        self.subscribers.append(callback)

    async def publish(self, event):
        for subscriber in self.subscribers:
            await subscriber(event)

async def service_a(event_bus, user_id):
    event = {"type": "UserRequested", "user_id": user_id}
    await event_bus.publish(event)

async def service_b(event):
    if event["type"] == "UserRequested":
        print(f"Processing user {event['user_id']}")

async def main():
    bus = EventBus()
    bus.subscribe(service_b)
    await service_a(bus, 123)

asyncio.run(main())
OutputSuccess
Alternatives
Batch Processing
Processes data in large groups at scheduled times rather than real-time communication.
Use when: Choose when real-time interaction is not required and throughput optimization is prioritized.
Polling
Clients repeatedly check for updates instead of receiving events asynchronously.
Use when: Choose when event-driven infrastructure is unavailable and update frequency is low.
Summary
Request-response communication waits for immediate replies, making it simple but tightly coupled and potentially blocking.
Event-driven communication uses asynchronous events to decouple services, improving scalability and fault tolerance.
Choosing between them depends on system requirements like latency sensitivity, complexity, and scale.

Practice

(1/5)
1. Which communication pattern is best when a service needs an immediate answer from another service?
easy
A. Event-driven pattern
B. Request-response pattern
C. Batch processing
D. File transfer

Solution

  1. Step 1: Understand request-response pattern

    This pattern involves one service sending a request and waiting for a direct reply from another service immediately.
  2. Step 2: Compare with event-driven pattern

    Event-driven is asynchronous and does not guarantee immediate response, so it is not suitable for immediate answers.
  3. Final Answer:

    Request-response pattern -> Option B
  4. Quick Check:

    Immediate answer = Request-response [OK]
Hint: Immediate reply means request-response pattern [OK]
Common Mistakes:
  • Confusing event-driven with immediate response
  • Thinking batch processing is real-time
  • Assuming file transfer is a communication pattern
2. Which of the following is the correct way to describe an event-driven system?
easy
A. Services emit events and other services react asynchronously.
B. Services send requests and wait for replies synchronously.
C. Services communicate only through shared databases.
D. Services batch process data at fixed intervals.

Solution

  1. Step 1: Define event-driven communication

    In event-driven systems, services emit events without waiting for immediate replies, and other services react to these events asynchronously.
  2. Step 2: Eliminate incorrect options

    Services send requests and wait for replies synchronously. describes request-response, C and D are unrelated to event-driven communication.
  3. Final Answer:

    Services emit events and other services react asynchronously. -> Option A
  4. Quick Check:

    Event-driven = asynchronous event emission [OK]
Hint: Event-driven means emit events, react later [OK]
Common Mistakes:
  • Mixing synchronous request-response with event-driven
  • Thinking event-driven requires waiting for replies
  • Confusing batch processing with event-driven
3. Consider this scenario: Service A sends a request to Service B and waits for a response. Meanwhile, Service C emits an event that Service B listens to and processes asynchronously. Which pattern does Service A use with Service B, and which pattern does Service C use with Service B?
medium
A. Service A uses request-response; Service C uses event-driven
B. Both use event-driven
C. Both use request-response
D. Service A uses event-driven; Service C uses request-response

Solution

  1. Step 1: Identify Service A and B interaction

    Service A sends a request and waits for a response from Service B, which is the request-response pattern.
  2. Step 2: Identify Service C and B interaction

    Service C emits an event that Service B processes asynchronously, which is event-driven communication.
  3. Final Answer:

    Service A uses request-response; Service C uses event-driven -> Option A
  4. Quick Check:

    Request-response = direct wait; Event-driven = async event [OK]
Hint: Request-response waits; event-driven emits and forgets [OK]
Common Mistakes:
  • Swapping patterns between services
  • Assuming all communication is synchronous
  • Ignoring asynchronous event processing
4. A developer implemented a microservice system where Service X sends an event and immediately expects a response from Service Y. What is the main issue with this design?
medium
A. Events must be stored in a database before processing.
B. Request-response pattern is not suitable for microservices.
C. Services should never communicate directly.
D. Event-driven systems do not support immediate responses; this breaks the pattern.

Solution

  1. Step 1: Understand event-driven communication

    Event-driven systems are asynchronous; services emit events without waiting for immediate replies.
  2. Step 2: Identify the design issue

    Expecting an immediate response after sending an event contradicts the asynchronous nature of event-driven systems, causing design problems.
  3. Final Answer:

    Event-driven systems do not support immediate responses; this breaks the pattern. -> Option D
  4. Quick Check:

    Event-driven ≠ immediate response [OK]
Hint: Events don't get immediate replies in event-driven [OK]
Common Mistakes:
  • Thinking request-response is bad for microservices
  • Believing services must never communicate directly
  • Confusing event storage with communication pattern
5. You are designing a large e-commerce system. For order placement, the user must get immediate confirmation. For inventory updates and shipping notifications, delays are acceptable. Which combination of communication patterns should you use?
hard
A. Use event-driven for order confirmation; request-response for inventory and shipping
B. Use request-response for all communications
C. Use request-response for order confirmation; event-driven for inventory and shipping
D. Use event-driven for all communications

Solution

  1. Step 1: Analyze order confirmation requirement

    User needs immediate confirmation, so request-response pattern fits best for order placement.
  2. Step 2: Analyze inventory and shipping updates

    These can be delayed and processed asynchronously, so event-driven pattern suits these tasks.
  3. Step 3: Combine patterns appropriately

    Use request-response for immediate feedback and event-driven for asynchronous updates to scale well and keep user experience smooth.
  4. Final Answer:

    Use request-response for order confirmation; event-driven for inventory and shipping -> Option C
  5. Quick Check:

    Immediate = request-response; delayed = event-driven [OK]
Hint: Immediate needs request-response; delays use event-driven [OK]
Common Mistakes:
  • Using event-driven for immediate confirmation
  • Using request-response for all async tasks
  • Ignoring user experience needs