This feature requires the LangGraph Agent Server. Run your agent locally with
langgraph dev or deploy it to LangSmith to use this pattern.Why join & rejoin?
Traditional streaming APIs tightly couple the client and server: if the client disconnects, the stream is lost. Join and rejoin breaks this coupling, enabling several important patterns:- Network interruptions: mobile users moving between cell towers or Wi-Fi networks can seamlessly resume
- Page navigation: users navigating away from a chat page and returning later without losing progress
- Mobile backgrounding: apps suspended by the OS can rejoin the stream when foregrounded
- Long-running tasks: agents performing multi-minute operations (research, code generation, data analysis) where users don’t need to keep the page open
- Multi-device handoff: start a conversation on your phone, rejoin on your desktop
Core concepts
The join/rejoin pattern involves three key mechanisms:| Method / Option | Purpose |
|---|---|
stream.stop() | Disconnect the client from the stream without stopping the agent |
stream.joinStream(runId) | Reconnect to an existing stream by its run ID |
onDisconnect: "continue" | Submit option that tells the server to keep running after client disconnects |
streamResumable: true | Submit option that enables the stream to be rejoined later |
stream.stop() is fundamentally different from cancelling a run. Stopping only disconnects the client. The agent continues processing server-side. To actually cancel the agent’s execution, you would use interrupt or cancel mechanisms instead.Setting up useStream
The key setup step is capturing the run_id from the onCreated callback so you can rejoin later.
Import your agent and pass typeof myAgent as a type parameter to useStream for type-safe access to state values:
Submitting with resumable options
When you submit a message, passonDisconnect: "continue" and streamResumable: true to enable the join/rejoin flow:
| Option | Default | Description |
|---|---|---|
onDisconnect | "cancel" | What happens when the client disconnects. "continue" keeps the agent running; "cancel" stops it. |
streamResumable | false | When true, the server retains the stream state so a client can rejoin later. |
Disconnecting from a stream
Callstream.stop() to disconnect the client. The agent continues processing server-side.
stop():
stream.isLoadingbecomesfalse- The message list retains all messages received up to the disconnect point
- The agent continues running on the server
- No new messages are received until you rejoin
Rejoining a stream
Callstream.joinStream(runId) with the saved run ID to reconnect:
stream.isLoadingbecomestrueagain- Any messages generated while disconnected are delivered
- New streaming messages resume in real-time
- If the agent has already finished, you receive the final state immediately
Building a connection status indicator
A visual indicator helps users understand whether they are actively receiving updates from the agent.Disconnect and rejoin controls
Provide explicit buttons for disconnecting and rejoining so users have full control:Persisting the run ID
For cross-session rejoin (e.g., the user closes the browser and returns later), persist the run ID to storage:Persisted run IDs should be cleaned up when a run completes. Listen for the stream to finish and remove the stored ID to avoid attempting to rejoin completed runs.
Error handling
Rejoining can fail if the run has expired, been deleted, or if the server has restarted. Handle these cases gracefully:Complete example
Best practices
- Always save the run ID: without it, rejoining is impossible. Use both component state and persistent storage for resilience.
- Show clear connection state: users should always know whether they are receiving live updates or viewing a snapshot.
- Auto-rejoin on visibility change: use the Page Visibility API to automatically rejoin when the user returns to the tab.
- Set reasonable timeouts: if a rejoin attempt takes too long, fall back to fetching the thread history instead.
- Clean up completed runs: remove persisted run IDs when the agent finishes to avoid stale rejoin attempts.
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

