Platform integration
Agent infrastructure
Event-driven vs request-response for agent integrations: how each pattern works, the trade-offs that matter, and which one fits which interaction in production.

Agent projects force an old integration question back onto the table. Do you call a system and wait for the answer, or publish an event and let subscribers react? Request-response feels obvious — the agent needs a result, so it asks for one. Event-driven feels modern — decouple everything, scale forever. Neither framing survives contact with production.
This comparison is for platform engineers, integration leads, and Heads of AI deciding how their agents will actually talk to the systems around them. The short version: request-response wins when the agent needs an answer before it can decide what to do next. Event-driven wins when the work is fire-and-forget, fan-out, or has to survive downstream systems being unavailable. Most real agent architectures use both — the mistake is picking one as a religion.
Request-response is the pattern every REST, GraphQL, and RPC call uses. A caller sends a request, blocks until a response comes back (or a timeout fires), and continues based on what it got. The contract is synchronous: the caller and the callee share a live connection for the duration of the call. HTTP is the transport most teams use, though gRPC and internal RPC frameworks follow the same model.
For agents, this maps cleanly onto tool calling. The model decides it needs a piece of information or wants to take an action. It emits a tool call. The runtime executes the call against a real API. The response comes back into the model's context, and the next reasoning turn uses it. Every foundation model provider's tool-calling API — Anthropic, OpenAI, Google — assumes synchronous request-response as the default. The agent asks; the tool answers.
Event-driven integration inverts the flow. Instead of a caller pulling data or triggering work directly, a producer publishes an event to a broker — Kafka, RabbitMQ, AWS SNS/SQS, Google Pub/Sub — and one or more consumers subscribe to that stream. The producer doesn't know who's listening. The consumer doesn't know who published. The broker holds the message until it's delivered, retried, or dead-lettered.
The pattern shows up in agent systems in three main places. First, as the trigger: a webhook or event stream wakes the agent up when something happens in a source system, rather than the agent polling on a timer. Second, as the durable work queue: the agent kicks off a long-running task, publishes an event, and lets a worker process do the heavy lifting. Third, as fan-out: one action needs to notify five downstream systems, and none of them should block each other. Webhooks are the most common event-driven surface most SaaS teams already expose, even if they don't call themselves event-driven.
Pick request-response when the agent's next reasoning step depends on the answer. If the model is deciding whether to escalate a ticket, it needs the ticket's current state now — not eventually. Every read-shaped tool call falls into this bucket: fetch a record, look up a user, search a database, get the current balance. The model can't reason forward without the data, so a synchronous call is the only pattern that fits.
It's also the right choice for writes where the agent needs confirmation. Creating a resource and immediately telling the user "done, here's the ID" requires the agent to know the ID. Charging a card and reporting success requires the response. In both cases the model is the state machine and the tool call is a step it has to complete before advancing. Idempotency keys make these calls safe to retry — event-driven back-ends don't remove that requirement, they just move it.
The other case: low-latency, low-fan-out interactions where introducing a broker is architectural overkill. If one agent calls one API and the round-trip is 200ms, you don't need Kafka. You need a well-designed REST API and a runtime that handles retries and circuit breakers properly.
Pick event-driven when the agent is reacting to something rather than initiating it. A support agent that should wake up when a new high-priority ticket lands doesn't want to poll the ticketing system every 30 seconds. It wants the ticketing system to push an event, and the agent runtime to spin up a run in response. This is what webhooks were designed for, and it's the cleanest fit for agent triggers.
Also pick it for long-running work. If the agent kicks off a report generation that takes four minutes, holding an HTTP connection open for that duration is fragile — timeouts fire, load balancers close idle connections, retries create duplicate work. Publishing a job event, letting a worker process it, and having the worker publish a completion event the agent picks up later is more robust. The agent's runtime needs to support this pattern explicitly: pause the run, resume on completion event, resume on timeout.
Fan-out is the third strong case. The agent completes an action that has to trigger five downstream systems — CRM update, notification, audit log, analytics, billing. Making the agent call each one synchronously creates five failure modes stacked on top of each other. Publishing one event and letting each system subscribe means each subscriber can fail, retry, and recover on its own schedule. The agent's job is done as soon as the event is on the broker.
Finally: bursty producers. If the agent has to react to spikes — 10,000 events in a minute during business hours, near-zero at night — a broker's queue is the natural buffer. Request-response systems have to solve back-pressure with rate limits and 429s, which the agent then has to handle. Event-driven systems solve it by letting the consumer lag.
The question isn't really "which pattern." It's "which pattern for which interaction." Production agent systems use request-response for tool calls the model needs answers to, and event-driven for triggers, long-running work, and fan-out. The architectural work is drawing the boundary — deciding which calls block the agent's reasoning loop and which get handed off to the async world.
Two cases worth naming. First: async request-response. Some tool calls take longer than the model's reasoning turn can wait for, but the model still needs the result. The pattern is a synchronous call that returns a job ID, followed by the agent polling or subscribing until the result is ready. This is technically request-response on the surface and event-driven underneath — and it's how most "long-running tool" implementations end up looking. Second: webhook reliability. If your agent depends on inbound webhooks to wake up, the delivery guarantees of the webhook system become the reliability floor of your agent. Signature verification, retry policy, and dead-letter handling all matter more than the model choice.
Start with request-response for the tool layer. It's what foundation model providers optimise for, it's what your APIs already speak, it's what your engineers can debug, and it fits the vast majority of tool calls agents actually make — reads, writes with confirmation, decisions the model needs to reason forward from. Get that layer right first: contracts, auth, idempotency, retries, rate limiting.
Add event-driven for the three cases it earns: triggers (agents that react to events rather than poll), long-running work (jobs the model shouldn't block on), and fan-out (one action, many downstream systems). Don't retrofit an event bus onto interactions that are already fine as synchronous calls. Every broker you add is a component that can lag, drop messages, or partition-imbalance in ways your synchronous stack can't.
The deciding variable, when it's genuinely close: does the model need the answer before the next reasoning turn? If yes, request-response. If no, event-driven is on the table. Everything else — cost, latency, coupling, scale — is secondary to that one question, because the model's reasoning loop is the constraint everything else is optimising for.
Stay up to date on the ever changing agentic landscape.