Skip to main content

Overview

LangGraph supports time travel through checkpoints:
  • Replay: Retry from a prior checkpoint.
  • Fork: Branch from a prior checkpoint with modified state to explore an alternative path.
Both work by resuming from a prior checkpoint. Nodes before the checkpoint are not re-executed (results are already saved). Nodes after the checkpoint re-execute, including any LLM calls, API requests, and interrupts (which may produce different results).

Replay

Invoke the graph with a prior checkpoint’s config to replay from that point.
Replay re-executes nodes—it doesn’t just read from cache. LLM calls, API requests, and interrupts fire again and may return different results. Replaying from the final checkpoint (no next nodes) is a no-op.
Replay Use get_state_history to find the checkpoint you want to replay from, then call invoke with that checkpoint’s config:

Fork

Fork creates a new branch from a past checkpoint with modified state. Call update_state on a prior checkpoint to create the fork, then invoke with None to continue execution. Fork
update_state does not roll back a thread. It creates a new checkpoint that branches from the specified point. The original execution history remains intact.

From a specific node

When you call update_state, values are applied using the specified node’s writers (including reducers). The checkpoint records that node as having produced the update, and execution resumes from that node’s successors. By default, LangGraph infers as_node from the checkpoint’s version history. When forking from a specific checkpoint, this inference is almost always correct. Specify as_node explicitly when:
  • Parallel branches: Multiple nodes updated state in the same step, and LangGraph can’t determine which was last (InvalidUpdateError).
  • No execution history: Setting up state on a fresh thread (common in testing).
  • Skipping nodes: Set as_node to a later node to make the graph think that node already ran.

Interrupts

If your graph uses interrupt for human-in-the-loop workflows, interrupts are always re-triggered during time travel. The node containing the interrupt re-executes, and interrupt() pauses for a new Command(resume=...).

Multiple interrupts

If your graph collects input at several points (for example, a multi-step form), you can fork from between the interrupts to change a later answer without re-asking earlier questions.

Subgraphs

Time travel with subgraphs depends on whether the subgraph has its own checkpointer. This determines the granularity of checkpoints you can time travel from.
By default, a subgraph inherits the parent’s checkpointer. The parent treats the entire subgraph as a single super-step — there is only one parent-level checkpoint for the whole subgraph execution. Time traveling from before the subgraph re-executes it from scratch.You cannot time travel to a point between nodes in a default subgraph — you can only time travel from the parent level.
See subgraph persistence for more on configuring subgraph checkpointers.