Skip to main content
LangGraph implements a streaming system to surface real-time updates. Streaming is crucial for enhancing the responsiveness of applications built on LLMs. By displaying output progressively, even before a complete response is ready, streaming significantly improves user experience (UX), particularly when dealing with the latency of LLMs. What’s possible with LangGraph streaming:
  • Stream graph state — get state updates / values with updates and values modes.
  • Stream subgraph outputs — include outputs from both the parent graph and any nested subgraphs.
  • Stream LLM tokens — capture token streams from anywhere: inside nodes, subgraphs, or tools.
  • Stream custom data — send custom updates or progress signals directly from tool functions.
  • Stream tool progress — track tool lifecycle events (start, progress, end, error) in real time.
  • Use multiple streaming modes — choose from values (full state), updates (state deltas), messages (LLM tokens + metadata), custom (arbitrary user data), tools (tool lifecycle events), or debug (detailed traces).

Supported stream modes

Pass one or more of the following stream modes as a list to the stream method:

Basic usage example

LangGraph graphs expose the stream method to yield streamed outputs as iterators.

Stream multiple modes

You can pass an array as the streamMode parameter to stream multiple modes at once. The streamed outputs will be tuples of [mode, chunk] where mode is the name of the stream mode and chunk is the data streamed by that mode.

Stream graph state

Use the stream modes updates and values to stream the state of the graph as it executes.
  • updates streams the updates to the state after each step of the graph.
  • values streams the full value of the state after each step of the graph.
Use this to stream only the state updates returned by the nodes after each step. The streamed outputs include the name of the node as well as the update.

Stream subgraph outputs

To include outputs from subgraphs in the streamed outputs, you can set subgraphs: true in the .stream() method of the parent graph. This will stream outputs from both the parent graph and any subgraphs. The outputs will be streamed as tuples [namespace, data], where namespace is a tuple with the path to the node where a subgraph is invoked, e.g. ["parent_node:<task_id>", "child_node:<task_id>"].
Note that we are receiving not just the node updates, but we also the namespaces which tell us what graph (or subgraph) we are streaming from.

Debugging

Use the debug streaming mode to stream as much information as possible throughout the execution of the graph. The streamed outputs include the name of the node as well as the full state.

LLM tokens

Use the messages streaming mode to stream Large Language Model (LLM) outputs token by token from any part of your graph, including nodes, tools, subgraphs, or tasks. The streamed output from messages mode is a tuple [message_chunk, metadata] where:
  • message_chunk: the token or message segment from the LLM.
  • metadata: a dictionary containing details about the graph node and LLM invocation.
If your LLM is not available as a LangChain integration, you can stream its outputs using custom mode instead. See use with any LLM for details.

Filter by LLM invocation

You can associate tags with LLM invocations to filter the streamed tokens by LLM invocation.

Filter by node

To stream tokens only from specific nodes, use stream_mode="messages" and filter the outputs by the langgraph_node field in the streamed metadata:

Stream custom data

To send custom user-defined data from inside a LangGraph node or tool, follow these steps:
  1. Use the writer parameter from the LangGraphRunnableConfig to emit custom data.
  2. Set streamMode: "custom" when calling .stream() to get the custom data in the stream. You can combine multiple modes (e.g., ["updates", "custom"]), but at least one must be "custom".

Stream tool progress

Use the tools stream mode to receive real-time lifecycle events for tool executions. This is useful for showing progress indicators, partial results, and error states in your UI while tools are running. The tools stream mode emits four event types:

Define tools that stream progress

To emit on_tool_event events, define your tool function as an async generator (async function*). Each yield sends intermediate data to the stream, and the return value is used as the tool’s final result.
Existing tools that return a Promise are fully compatible. They emit on_tool_start and on_tool_end events but no on_tool_event events.

Consume tool events server-side

Pass streamMode: ["tools"] (or combine with other modes) to graph.stream():

Use tool progress in React with useStream

The useStream hook from @langchain/langgraph-sdk/react exposes a toolProgress array when you include "tools" in your stream modes. Each entry is a ToolProgress object that tracks the current state of a running tool:
This example shows a complete agent with async-generator tools that stream search progress to a React UI.Agent definition:
React component with progress cards:

tools vs custom stream mode

Both stream modes can surface tool progress, but they serve different purposes:
  • tools — automatically emits structured lifecycle events (on_tool_start, on_tool_event, on_tool_end, on_tool_error) with no code changes needed in your tools beyond using async function*. The useStream hook provides the reactive toolProgress array out of the box.
  • custom — gives you full control over what data is emitted and when using config.writer(). Use this when you need freeform data that doesn’t map to the tool lifecycle, or when you want to stream from nodes (not just tools).

Use with any LLM

You can use streamMode: "custom" to stream data from any LLM API — even if that API does not implement the LangChain chat model interface. This lets you integrate raw LLM clients or external services that provide their own streaming interfaces, making LangGraph highly flexible for custom setups.
Let’s invoke the graph with an AIMessage that includes a tool call:

Disable streaming for specific chat models

If your application mixes models that support streaming with those that do not, you may need to explicitly disable streaming for models that do not support it. Set streaming: false when initializing the model.
Not all chat model integrations support the streaming parameter. If your model doesn’t support it, use disableStreaming: true instead. This parameter is available on all chat models via the base class.