skip to content

questions

6

In distributed systems, what is the core difference between a request-driven (synchronous request/response) interaction and an event-driven (asynchronous event) interaction between two services?

level: juniorimportance: must knowfreq 75%

answer

  1. phone call vs letter
  2. temporal coupling axis
  3. autonomy & resilience vs eventual consistency
  4. call stack vs event graph

basics

~20 s

In request-driven, one service asks another and waits for an answer right away, like a phone call. In event-driven, a service announces "this happened" and moves on, and other services react whenever they get around to it, like a text message.

solid answer

~30 s

Request-driven means a caller sends a request and blocks (or awaits) until the callee responds, coupling both parties in time — both must be up and reachable simultaneously, and the caller directly depends on the callee's latency and availability. Event-driven means a producer publishes a fact about something that already happened (an event) to a broker/log and continues without waiting; consumers subscribe and process it independently, on their own schedule. The key axis is temporal coupling: request/response requires both sides present "now"; events decouple producer and consumer in time via a durable intermediary.

go deeper

for a junior

Should describe the basic mental model correctly (caller waits vs caller doesn't wait) and give one plausible example of each style. Doesn't need to discuss consistency or observability trade-offs in depth.

for a middle

Should articulate the temporal-decoupling concept explicitly and connect it to at least one concrete consequence (availability or consistency) rather than just describing mechanics.

for a senior

Should discuss trade-offs on both sides with production consequences (cascading failure vs consumer lag/staleness) and pick the right style per use case within a single system.

for a principal

Should reason about this as an architectural decision with organizational consequences — team autonomy, deployment coupling, and how the choice affects the org's ability to evolve services independently — not just the technical mechanics.

Request-driven and event-driven are two fundamentally different communication styles for making distributed systems talk to each other, and the difference isn't really about the transport (HTTP vs a message broker) — it's about **what each side commits to and when**. ## Request-driven: the caller waits In a **request-driven** (synchronous request/response) interaction, service A calls service B and, conceptually, blocks until B replies. Even when the call is technically non-blocking (a Promise, a Kotlin coroutine, a callback), A's business logic cannot proceed past that call site until it has B's answer — there's a causal, in-the-moment dependency. This means: | # | What follows from it | |---|---| | 1 | Both A and B must be reachable and healthy at the same instant. | | 2 | A's tail latency includes B's tail latency plus network round trip. | | 3 | If B is down, A's request fails immediately, and A must decide right there how to handle it (retry, fallback, error to its own caller). | The mental model is a synchronous function call or a phone call — you dial, you wait, you get an answer or a busy signal. ## Event-driven: publish and walk away In an **event-driven** interaction, service A does something in its own transaction (e.g., "order placed"), then publishes a fact about that — an **event** — to a broker or log (Kafka, RabbitMQ, SNS/SQS, an outbox table read by a relay). A does not wait for anyone to consume that event; from A's point of view, the interaction is over once the event is durably stored. Zero or more consumers (B, C, D…) subscribe to that event type and process it whenever they poll or receive it — a second later, or an hour later if they were down. The mental model is a postal letter or a bulletin-board announcement: you post it and walk away; whoever reads it, reads it on their own schedule. ## What each style buys The distinction exists because the core value event-driven design buys is **temporal decoupling** — producer and consumer no longer need to be simultaneously available. This unlocks two related benefits: - **Autonomy** — each service can deploy, scale, and fail independently without a synchronous chain reaction. - **Resilience** — a consumer outage doesn't cascade back to the producer; events simply queue up and get processed once the consumer recovers. Request-driven communication, by contrast, buys you an immediate, in-band answer — you know synchronously whether the operation succeeded, and can return that result straight up your own call stack to whoever is waiting on you. ## The trade-offs The trade-offs cut both ways. Choosing events costs you: - **Strong, immediate consistency.** Because processing is deferred, the rest of the system is momentarily out of sync with the fact that just occurred — this is "eventual consistency," and callers who need a same-millisecond guarantee can't get it from an event alone. - **Straightforward reasoning.** A request-driven call chain is a stack you can read top to bottom; an event-driven flow is a graph of independent reactions whose overall order and effect you must reconstruct mentally or with tracing tooling, because there's no single thread of control. Choosing requests costs you availability and autonomy: a synchronous chain is only as available as its least-available link, and it tightly couples deploy/scaling of both sides. ## The classic failure of each style In production, each style has its own classic failure. - **Request-driven — cascading latency/failure.** A slow downstream service without a timeout or circuit breaker drags every upstream caller down with it (thread-pool exhaustion, connection-pool starvation). - **Event-driven — silent staleness, or duplicate/out-of-order processing.** A consumer falls behind (consumer lag) and nobody notices until a customer complains their order status is "stuck," or a message is redelivered after a crash and a non-idempotent handler double-charges someone. ## A worked example: checkout Consider checkout at an e-commerce site as a worked example. Payment authorization is almost always request-driven — the customer is sitting there waiting for "your card was charged" or "declined," so it has to be synchronous and give an immediate answer. But once payment succeeds, "notify the warehouse to prepare the shipment," "send a confirmation email," and "update the recommendation engine" are classic event-driven work: an `OrderPlaced` event is published once, and inventory, email, and analytics services each react independently, none of them blocking the checkout response, and none of them able to bring checkout down if they're temporarily unavailable.

  • Does using a message broker automatically make an interaction 'event-driven'?
    No — you can use a broker for request/response too, e.g., RPC-over-Kafka where a caller publishes a request message and blocks waiting for a correlated reply message on another topic. What defines event-driven is that the producer doesn't wait for or depend on a reply; the transport is a separate concern from the interaction style.
  • Can a single system mix both styles?
    Yes, and most production systems do — synchronous request/response for the parts a human or upstream caller is actively waiting on, like an HTTP checkout call, and asynchronous events for background side effects like notifications, analytics, or cross-service state propagation. The skill is drawing that line consciously rather than defaulting to one style everywhere.
  • If a consumer's event handler crashes halfway through, what typically happens compared to a synchronous call failing?
    In request-driven code, the caller sees the failure immediately and can react in the same code path. In event-driven code, the broker typically redelivers the message (at-least-once delivery) after a visibility timeout or lack of ack, so the handler runs again later — which means the handler must be idempotent or the retry can cause duplicate side effects.

Request-driven is a phone call — you dial and wait on the line for an answer; event-driven is mailing a letter or posting a notice on a bulletin board — you post it and move on, and readers pick it up whenever they check.

saying these in an interview costs you the question

  • Says event-driven and asynchronous are the same thing as 'using a queue', without mentioning that the producer doesn't wait for a response
  • Claims event-driven systems are strictly 'more scalable' with no mention of the eventual-consistency cost
  • Cannot name a concrete case where synchronous request/response is the correct choice
  • Thinks 'event-driven' means every service call must go through a broker
  • Confuses message queues used for RPC (request/reply over a queue) with genuine event-driven decoupling

context

open as a page

You're deciding whether a 'user updated their shipping address' change should trigger a synchronous API call to the shipping service or publish an AddressUpdated event instead. What's the actual trade-off you're making, beyond 'events are more scalable'?

level: middleimportance: must knowfreq 80%

basics

~20 s

If you call directly, you know right away it worked, but you depend on that service being up. If you publish an event, you don't depend on it being up right now, but you don't know immediately whether it processed the change, and it might be out of sync for a bit.

open as a page

Why does tracing the root cause of an incorrect order status typically take longer in an event-driven fan-out architecture than in a synchronous request/response chain, and what practices reduce that cost?

level: seniorimportance: must knowfreq 65%

basics

~20 s

In a normal call chain, you can follow one thread step by step in the logs. In an event system, many independent services react on their own schedule, so there's no single thread to follow, and you need extra tools like tracking IDs and dashboards to piece the story back together.

open as a page

A checkout service publishes an OrderPlaced event that an inventory service consumes asynchronously to decrement stock. Immediately after checkout, the customer refreshes the product page and still sees the item as 'in stock' with the same quantity as before their purchase. What's happening, and what design choices reduce how often customers see this?

level: middleimportance: should knowfreq 60%

basics

~20 s

The inventory count hasn't caught up yet because the update happens a little after the purchase, not instantly. You can shrink that gap or accept it as normal, but some delay is expected with this design.

open as a page

When a downstream service (say, an email/notification service) goes completely offline for 30 minutes, how does the blast radius differ between a request-driven design where the upstream service calls it synchronously versus an event-driven design where the upstream service publishes an event for it?

level: seniorimportance: should knowfreq 55%

basics

~20 s

If the call is direct and synchronous, the upstream service can get stuck or start failing too while the other service is down. If it's an event, the upstream service is fine — the messages just pile up and get processed once the other service comes back.

open as a page

A platform team is under pressure to 'go event-driven' across the board after a successful migration of one workflow. As the architect, when would you push back and keep a workflow request-driven instead?

level: principalimportance: should knowfreq 45%

basics

~20 s

Not every part of the system benefits from going async. If people need an instant yes/no answer, if two things must happen together perfectly, or if the team can't yet trace bugs across services, staying with direct calls is often safer.

open as a page