Skip to main content
For new applications, we recommend event streaming—the typed-projection API introduced in LangGraph v1.2. Event streaming gives you separate iterators per projection (messages, values, subgraphs, output) so you can consume them independently instead of branching on stream_mode chunks.
This page covers LangGraph’s stream-mode API. It exposes graph execution through stream modes such as updates, values, messages, custom, checkpoints, tasks, and debug. Use it when you need direct access to graph-runtime events or specific stream-mode output.

Get started

Basic usage

LangGraph graphs expose the stream (sync) and astream (async) methods to yield streamed outputs as iterators. Pass one or more stream modes to control what data you receive.
Output
Output
Debug streaming events, inspect token-by-token LLM output, and monitor latency with LangSmith. Follow the tracing quickstart to get set up.

Stream output format (v2)

Requires LangGraph >= 1.1. All examples on this page use version="v2".
Pass version="v2" to stream() or astream() to get a unified output format. Every chunk is a StreamPart dict with a consistent shape — regardless of stream mode, number of modes, or subgraph settings:
Each stream mode has a corresponding TypedDict containing ValuesStreamPart, UpdatesStreamPart, MessagesStreamPart, CustomStreamPart, CheckpointStreamPart, TasksStreamPart, DebugStreamPart. You can import these types from langgraph.types. The union type StreamPart is a disjoing union on part["type"], enabling full type narrowing in editors and type checkers. With v1 (default), the output format changes based on your streaming options (single mode returns raw data, multiple modes return (mode, data) tuples, subgraphs return (namespace, data) tuples). With v2, the format is always the same:
The v2 format also enables type narrowing, which means you can filter chunks by chunk["type"] and get the correct payload type. Each branch narrows part["data"] to the specific type for that mode:

Stream modes

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

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.
Output

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.
Manual config required for async in Python < 3.11 When using Python < 3.11 with async code, you must explicitly pass RunnableConfig to ainvoke() to enable proper streaming. See Async with Python < 3.11 for details or upgrade to Python 3.11+.

Filter by LLM invocation

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

Omit messages from the stream

Use the nostream tag to exclude LLM output from the stream entirely. Invocations tagged with nostream still run and produce output; their tokens are simply not emitted in messages mode. This is useful when:
  • You need LLM output for internal processing (for example structured output) but do not want to stream it to the client
  • You stream the same content through a different channel (for example custom UI messages) and want to avoid duplicate output in the messages stream

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:

Custom data

To send custom user-defined data from inside a LangGraph node or tool, follow these steps:
  1. Use get_stream_writer to access the stream writer and emit custom data.
  2. Set stream_mode="custom" when calling .stream() or .astream() to get the custom data in the stream. You can combine multiple modes (e.g., ["updates", "custom"]), but at least one must be "custom".
No get_stream_writer in async for Python < 3.11 In async code running on Python < 3.11, get_stream_writer will not work. Instead, add a writer parameter to your node or tool and pass it manually. See Async with Python < 3.11 for usage examples.

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>").
With version="v2", subgraph events use the same StreamPart format. The ns field identifies the source:
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.

Checkpoints

Use the checkpoints streaming mode to receive checkpoint events as the graph executes. Each checkpoint event has the same format as the output of get_state(). Requires a checkpointer.

Tasks

Use the tasks streaming mode to receive task start and finish events as the graph executes. Task events include information about which node is running, its results, and any errors. Requires a checkpointer.

Debug

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.
The debug mode combines checkpoints and tasks events with additional metadata. Use checkpoints or tasks directly if you only need a subset of the debug information.

Multiple modes at once

You can pass a list as the stream_mode parameter to stream multiple modes at once. With version="v2", every chunk is a StreamPart dict. Use chunk["type"] to distinguish between modes:

Advanced

Use with any LLM

You can use stream_mode="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 disable_streaming=True instead. This parameter is available on all chat models via the base class.

Migrate to v2

The v2 streaming format (used throughout this page) provides a unified output format. Here’s a summary of the key differences and how to migrate:

v2 invoke format

When you pass version="v2" to invoke() or ainvoke(), it returns a GraphOutput object with .value and .interrupts attributes:
With any stream mode other than the default "values", invoke(..., stream_mode="updates", version="v2") returns list[StreamPart] instead of list[tuple].
Dict-style access on GraphOutput (result["key"], "key" in result, result["__interrupt__"]) still works for backwards compatibility but is deprecated and will be removed in a future version. Migrate to result.value and result.interrupts.
This separates state from interrupt metadata. With v1, interrupts are embedded in the returned dict under __interrupt__:

Pydantic and dataclass state coercion

When your graph state is a Pydantic model or dataclass, v2 values mode automatically coerces output to the correct type:

Async with Python < 3.11

In Python versions < 3.11, asyncio tasks do not support the context parameter. This limits LangGraph ability to automatically propagate context, and affects LangGraph’s streaming mechanisms in two key ways:
  1. You must explicitly pass RunnableConfig into async LLM calls (e.g., ainvoke()), as callbacks are not automatically propagated.
  2. You cannot use get_stream_writer in async nodes or tools—you must pass a writer argument directly.