Async Long-Running Tool Calls
Handling tool calls that take minutes rather than seconds -- checkpoint-and-suspend patterns, async polling, webhook resumption, SSE progress streaming, durable execution with Temporal and Step Functions, and idempotency requirements for retriable tool invocations.
Overview
Overview
Standard LLM tool use assumes a tool returns inside the inference timeout, typically a few seconds. A data pipeline, batch job, video transcode or fine-tuning run can take five minutes to an hour, and bridging that gap without holding a server connection open takes patterns from both agent orchestration and distributed systems.
The fundamental mismatch
LLMs are built for synchronous request-response cycles. API servers, load balancers and connection pools assume the same, with hard timeouts typically in the 30-60 second range, so a 5-minute pipeline run breaks every timeout at every layer.
The fix is never to hold the connection open. The agent instead:
- Initiates the long-running task.
- Records that it started, by storing job_id in state.
- Releases the connection immediately.
- Resumes from a checkpointer snapshot when the task completes.
- Checkpointer — Persists agent state while it is suspended
- Webhook mechanism — Lets the external task announce completion
- Idempotent tool invocations — Makes retry and replay safe
The three patterns
- Checkpoint-suspend-webhook-resume — Start the job, store job_id, interrupt; the webhook writes the result and re-invokes the same thread_id — No — The canonical LangGraph choice
- Async polling — A polling node checks a status endpoint and loops with exponential backoff — Yes — The service exposes only a status endpoint, no webhooks
- SSE streaming — Server-Sent Events push progress ("started", "20% complete", "complete, resuming agent") to the browser — No — User experience, decoupled from agent resumption
> [!NOTE] For jobs longer than a few minutes, checkpoint-suspend-webhook beats polling because polling keeps a live execution thread busy.
Pattern 1 state
The tool node starts the pipeline, stores the job_id and triggers a graph interrupt. The webhook handler looks up the thread_id for that job_id, writes the result with graph.update_state() and calls graph.invoke() on the same thread_id.
> [!IMPORTANT] Generate the idempotency key in state before triggering the pipeline. On a crash and replay, the same key goes to the pipeline service, which returns the existing job_id instead of starting a second run.
Durable execution: Temporal and Step Functions
For workflows spanning hours or days, LangGraph checkpointers are often not enough; they are built for conversation-length persistence.
Temporal and AWS Step Functions provide durable execution primitives:
- Activity retries with configurable policies.
- Workflow versioning.
- Event history replay.
- Saga patterns for multi-step compensation.
> [!TIP] Reach for Temporal or Step Functions when you need exactly-once execution, multi-hour fault tolerance or saga compensation logic.
Interview questions
- How do you handle long-running asynchronous tool calls? For example, if an agent triggers a data pipeline that takes 5 minutes, how do you manage the agent's state and the user experience?
- What happens if the agent process crashes while waiting for the 5-minute pipeline? How do you recover?
- How would you design the user experience so the user knows what is happening during a 5-minute wait?
Sign up free to read the full topic
More Agentic AI topics
Start free on Cariara · Coding problems · System design studio