Join and rejoin lets you disconnect from a running agent stream without stopping the agent, then reconnect to it later. The agent continues executing server-side while the client is away, and you pick up the stream exactly where you left off.Documentation Index
Fetch the complete documentation index at: https://langchain-5e9cc07a-preview-cbuipl-1779916257-33d1bcf.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
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 |
|---|---|
threadId | Bind the stream to the LangGraph thread you want to observe |
onThreadId | Persist newly-created thread IDs so a remount can reconnect |
stream.disconnect() | Leave the stream client-side while the agent keeps running server-side |
Remount with the same threadId | Reattach to in-flight work for that thread |
Join/rejoin uses
stream.disconnect(), not stream.stop(). By default, stream.stop() cancels the active run: it disconnects the client and cancels the run on the server. For join/rejoin, call stream.disconnect() (alias for stop({ cancel: false })) so the agent continues processing while you are away.To cancel execution explicitly from app code, use stream.stop() or client.runs.cancel.Setting up useStream
The key setup step is persisting threadId. When the component remounts with
the same thread ID, the stream attaches to the thread’s current state and any
in-flight run.
The code examples use
useStream<typeof myAgent> for type-safe stream state. See Type inference for Python or JavaScript backends.Submitting messages
Submit messages normally. The thread ID binding is what allows a later remount to reconnect to the same conversation:Disconnecting from a stream
Callstream.disconnect() to leave the stream without cancelling the run. The agent continues processing server-side.
stream.stop() here — by default it cancels the run on the server.
After calling disconnect():
stream.isLoadingbecomesfalse- Your own
connectedflag should also becomefalse - 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
Remount the stream consumer with the saved thread ID to reconnect. In React, the demo bumps amountKey; in other frameworks, use the equivalent remount or
conditional-render pattern:
connectedbecomestrue- Any messages generated while disconnected are delivered
- New streaming messages resume in real-time
- If the agent is still running,
stream.isLoadingbecomestrue; if it has already finished, you receive the final state immediately
Best practices
- Use
disconnect()for join/rejoin,stop()to cancel: navigating away or backgrounding the app should callstream.disconnect(). A user-facing “Stop” or “Cancel” button should callstream.stop()(orclient.runs.cancel). - Always save the thread 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 stale threads: remove persisted thread IDs when the user starts over or the backend reports that the thread is unavailable.
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

