Event-Driven vs Request-Driven¶
1. Decision¶
Choose Request-Driven Architecture (REST, gRPC) for synchronous, point-to-point operations where the client requires an immediate response or return value before proceeding; choose Event-Driven Architecture (Kafka, RabbitMQ, EventBridge) for decoupled, asynchronous, broadcast, and highly scalable systems where services react independently to state change notifications ("events").
2. 30-Second Answer¶
Request-Driven Architecture (Point-to-Point) relies on explicit synchronous request-response calls. Service A invokes Service B and waits for a response. It is easy to reason about, simple to trace, and well-suited for interactive CRUD flows, but creates temporal coupling, cascading latency chains, and reduced availability (if Service B is down, Service A fails). Event-Driven Architecture (EDA) operates on asynchronous event notifications. Services emit immutable business facts (OrderPlaced, UserRegistered) to a message broker without knowing who the consumers are. Independent consumer services listen and react asynchronously. EDA delivers extreme horizontal scalability, fault isolation, and temporal decoupling, but introduces eventual consistency, out-of-order event handling, and complex debugging.
3. Decision Matrix¶
| Option | Best For | Avoid When | Latency | Scalability | Consistency | Operational Complexity |
|---|---|---|---|---|---|---|
| Request-Driven Architecture (REST / gRPC) | Immediate user feedback required (login, payment gateway, search query), interactive APIs, simple linear workflows | Heavy background jobs (>1s), broad 1:N event fanout, high-velocity metric ingestion | Low per hop; Cumulative across multi-service chains | Bounded by slowest downstream dependency | Immediate / Strong | Low |
| Event-Driven Architecture (Kafka / SQS / EventBridge) | Decoupled microservices, broadcast notifications (1:N fanout), stream processing (Flink), high-throughput logging, CDC pipelines | Synchronous user workflows requiring immediate validation returns | High (Queue latency + consumer processing time) | Extremely High (Decoupled producer and consumer scaling) | Eventual Consistency | Medium to High |
4. Selection Rules¶
| Requirement | Best Choice | Rationale / Example |
|---|---|---|
| Immediate Interactive User Response (Login / Checkout) | Request-Driven | Client requires immediate HTTP 200 OK or 400 Bad Request confirmation |
| Broadcast Single Event to 5 Independent Services | Event-Driven | OrderPlaced event notifies Inventory, Billing, Shipping, Email, & Analytics services |
| Protect Database from Flash Traffic Spikes | Event-Driven | Buffer incoming order events in Kafka/SQS queue to process at a controlled rate |
| Synchronous Real-Time Data Fetching (Search / Aggregation) | Request-Driven | API Gateway queries microservice directly for current user profile details |
| Plug-and-Play Architecture Expansion | Event-Driven | Add a new Fraud Detection service listening to PaymentEvent with ZERO producer code changes |
5. Tradeoffs¶
- Immediate Execution Feedback vs Temporal Decoupling
- Gain (Request): Client receives immediate execution results or error stack traces.
- Lose (Request): Sender thread blocks; if receiver is down, the request fails (temporal coupling).
- System Availability Isolation vs Eventual Consistency
- Gain (Event): Producers accept writes even if all downstream consumer services are completely dead.
- Lose (Event): System state is temporarily inconsistent across microservices (Requires Saga pattern).
- Traffic Spike Buffering vs Backpressure Queue Lag
- Gain (Event): Message brokers absorb 100,000 QPS spikes, feeding workers at a safe processing rate.
- Lose (Event): Queue backpressure increases processing latency from milliseconds to minutes/hours.
- Architectural Simplicity vs Out-of-Order Event Handling
- Gain (Request): Linear code execution; easy local debugging and stack tracing.
- Lose (Event): Must handle out-of-order events, duplicate deliveries, and idempotency checks.
- Decoupled Architecture Autonomy vs Complex Observability
- Gain (Event): Producers emit events without knowing who consumes them.
- Lose (Event): Difficult to track end-to-end distributed transaction flows without OpenTelemetry context injection.
6. Interview Counter Questions¶
- What is the difference between an Event Notification, Event-Carried State Transfer, and Event Sourcing?
- What is Temporal Coupling and how does Event-Driven Architecture eliminate it?
- How do you implement End-to-End Tracing across an Event-Driven Architecture (W3C Traceparent)?
- What happens when an event consumer receives messages out-of-order?
- How do you handle database updates and event publishing atomically (Transactional Outbox Pattern)?
- What is the difference between Choreography and Orchestration in Event-Driven Sagas?
- How does Backpressure work in Event-Driven Systems vs Request-Driven Systems?
- When is Event-Driven Architecture an over-engineering anti-pattern?
- How do you guarantee Idempotency in Event-Driven consumers?
- How do Schema Registries (Confluent Schema Registry / Avro) enforce event contract evolution?
7. Gold Standard Answers¶
- Event Notification: Tiny event stating something happened (
{"order_id": 123}). Event-Carried State Transfer: Event includes full entity payload so consumers don't call producer back. Event Sourcing: Events are the primary state of record. - Temporal Coupling means Service A requires Service B to be online at the exact same millisecond. EDA eliminates temporal coupling: Service A publishes to Kafka and finishes; Service B processes the message whenever it is online.
- Inject W3C
traceparentheaders into message metadata headers during publishing. Consumer workers extract metadata and attach the span to their local OpenTelemetry trace context. - Out-of-order events (e.g.
OrderShippedarrives beforeOrderCreated): Consumers check local entity version numbers. If sequence is wrong, buffer the event in Redis or reject/re-queue until the prerequisite event arrives. - Transactional Outbox Pattern: App writes domain change AND event payload into an
outboxDB table inside 1 local ACID transaction. Debezium CDC reads outbox table WAL and publishes to Kafka reliably. - Choreography: Services react to published events autonomously without a central manager. Orchestration: A central service (Temporal / Step Functions) explicitly directs and tracks event execution steps.
- Request-Driven: Receiver returns
HTTP 429or drops connections under load. Event-Driven: Message broker buffers incoming events on disk/memory, allowing consumers to pull at their own processing speed. - Anti-pattern for: small teams (<15 devs), simple CRUD web apps, workflows requiring instant synchronous user feedback, or systems lacking proper message broker observability.
- Store processed
event_idin Redis or DBUNIQUEindex. Consumer checks key before processing; if processed, skip execution and acknowledge event. - Producers register JSON/Avro schemas with Schema Registry. Schema Registry validates that new event versions are backward-compatible before allowing producers to publish to Kafka topics.
8. Common Mistakes¶
- Using Request-Driven synchronous calls for long-running background tasks (>2 seconds).
- Publishing events to Kafka directly inside HTTP controllers without using the Transactional Outbox Pattern (risks lost events on app crash).
- Failing to make Event-Driven consumers idempotent, causing duplicate side effects during message re-deliveries.
- Using Event-Driven architecture for simple user authentication or checkout flows requiring immediate synchronous HTTP responses.
- Emitting un-versioned JSON events without a Schema Registry, breaking downstream consumers during field changes.
9. Keywords¶
Event-Driven Architecture (EDA), Request-Driven Architecture, Temporal Coupling, Event Notification, Event-Carried State Transfer, Transactional Outbox Pattern, Choreography, Orchestration, Backpressure, Schema Registry, Avro, Idempotency, W3C Traceparent.
10. Cheat Sheet¶
- Core Difference: Request-Driven = Synchronous point-to-point call (Caller blocks waiting for response); Event-Driven = Asynchronous broadcast event (Producer emits fact & forgets).
- Temporal Coupling: Request-Driven requires both services online simultaneously; Event-Driven isolates availability.
- Reliable Publishing: Always use Transactional Outbox Pattern (Write DB + Outbox table in 1 transaction \(\rightarrow\) CDC to Kafka).
- Consumer Rules: All event consumers MUST be Idempotent and handle Out-of-Order Events using sequence versioning.
- Event Contracts: Use Schema Registries (Avro/Protobuf) to enforce backward compatibility on event payloads.
- Tracing: Inject W3C
traceparentheaders into message metadata for end-to-end OpenTelemetry tracing.