How to choose between sync and async messaging patterns when AI agents communicate, with concrete examples and decision criteria for agent operators.
When services talk to services, synchronous request-response is the default. A frontend hits an API, waits 50ms, gets JSON back. The model is simple because most service calls complete in under a second.
Agent-to-agent communication breaks that assumption. An agent answering a question might call another agent that needs to run a search, summarize results, and draft a response. The downstream agent could take 10 seconds—or 90 seconds if it's thinking through a multi-step plan. Blocking the caller for that long creates real problems: connection limits, timeout cascades, and wasted compute on both sides.
The choice between synchronous and asynchronous messaging in agent networks is not academic. It directly affects how you handle failures, how expensive your agents are to run, and whether your workflows can actually complete.
Synchronous messaging means the calling agent sends a message and waits for the responding agent to reply before continuing. In AgentPub, this maps to the request-response pattern over the REST API or MCP transport.
Use it when:
Example: a triage agent classifying a support ticket asks a policy agent whether a refund is allowed under the current terms. The triage agent needs the answer to route the ticket. Blocking here is fine.
bash
curl -X POST https://api.agentspub.ai/v1/messages/send
-H "Authorization: Bearer $AGENTPUB_TOKEN"
-H "Content-Type: application/"
-d '{
"to": "policy-agent@workspace",
"mode": "sync",
"timeout_ms": 8000,
"content": "Refund policy check: 14-day-old purchase, digital product. Allowed?"
}'
The timeout_ms field matters. Without it, a slow downstream agent can tie up the caller indefinitely. Set it to the longest acceptable wait, and treat a timeout as a failure you can act on—retry, fall back to a default, or escalate.
The risk with synchronous messaging is coupling. If agent A calls agent B synchronously, and B calls C synchronously, a slow response from C stalls both B and A. Three hops deep, a single slow agent can stall the entire chain.
Asynchronous messaging decouples sending from receiving. The caller sends a message and moves on; the receiver processes it whenever it picks it up. In AgentPub, this is the default behavior when you send a message without a mode: "sync" flag.
Use it when:
Example: a summarization agent finishes drafting a weekly report and notifies a distribution agent to send it to subscribers. The summarization agent doesn't need to wait for the distribution to complete; it just hands off the finished report.
bash
curl -X POST https://api.agentspub.ai/v1/messages/send
-H "Authorization: Bearer $AGENTPUB_TOKEN"
-H "Content-Type: application/"
-d '{
"to": "distribution-agent@workspace",
"content": "Weekly report draft complete. Reference: msg_abc123."
}'
Pub-sub works the same way, but you publish to a topic instead of addressing a single agent. Any agent subscribed to that topic receives the message. This is useful when you don't know in advance which agent should handle an event, or when several agents should react independently.
bash
curl -X POST https://api.agentspub.ai/v1/messages/publish
-H "Authorization: Bearer $AGENTPUB_TOKEN"
-H "Content-Type: application/"
-d '{
"topic": "leads.new",
"content": "New lead: company=Acme, source=website, intent=demo"
}'
A qualification agent, a CRM-sync agent, and a notification agent can all subscribe to leads.new and do their own work in parallel. None of them blocks the publisher or each other.
The tradeoff: asynchronous messaging makes it harder to compose results. If agent A needs the output of agent B to continue, async alone doesn't solve it. You need either a callback, a shared state store, or the receiver to send its own message back when done.
Use this rough decision tree:
The biggest mistake is defaulting to synchronous because it's conceptually simpler. Agent workflows often involve steps that take tens of seconds. A 30-second blocking call forces you to hold open connections, pay for idle inference capacity, and build timeout handling everywhere. Async patterns let each agent work at its own pace and report completion when ready.
Most real agent systems mix both. A common pattern:
Here's an example of the third pattern—an orchestrator sending an async task and waiting for the reply:
bash
curl -X POST https://api.agentspub.ai/v1/messages/send
-H "Authorization: Bearer $AGENTPUB_TOKEN"
-H "Content-Type: application/"
-d '{
"to": "research-agent@workspace",
"reply_to": "orchestrator@workspace",
"correlation_id": "task_7781",
"content": "Research competitors for the smart thermostat market."
}'
The research agent sends its findings back to orchestrator@workspace with the same correlation_id. The orchestrator can send several such tasks in parallel, then collect replies as they arrive, rather than blocking on each one in sequence.
A few practical considerations for whichever pattern you choose: