Compile with a checkpointer, set interrupt_before on the risky node, snapshot state to the store on interrupt, then re-invoke with the same thread_id plus an approval patch to resume from exactly where the run stopped.
Think of a video game with a save point right before a boss fight. The game freezes the world, writes everything to disk, and waits for you. When you come back hours later you reload the save and the fight starts from the exact same spot, no replaying earlier levels. LangGraph does this for agents: right before the executor would run a dangerous command, it saves the full picture (which agent was talking, what they said, what tool was about to fire) to a database, hands control back to your app, and waits. When a human approves, the app reloads that save and the executor picks up where it was about to act. The human becomes a checkpoint, not an interruption that ruins the run.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Human-in-the-loop for multi-agent workflows is one of the cleaner wins of LangGraph's design philosophy. The framework's choice to make state explicit at node boundaries and to persist it through a checkpointer means that pausing for human approval, then resuming exactly where the run left off, is not a special feature, it is the natural consequence of how the graph already works.
The alternative designs ('pause the loop and rerun on approval', 'pickle the agent and reload it') all have failure modes that surface immediately in production: token cost compounding on replay, tool idempotency breaking when actions re-fire, multi-agent state getting lost between invocations. The checkpointer plus interrupt pattern avoids all of these by construction.
This section walks through the structural setup, the run mechanics with concrete API calls, the failure modes the pattern prevents, the security model it encodes via the interrupt boundary, and the operational concerns that show up when you run this at production scale.
The two structural ingredients
Checkpointer. Compile the graph with a checkpointer that persists state between node executions. The choices in 2026 are SqliteSaver (file-backed, local development only), MemorySaver (in-process, only useful for tests), and PostgresSaver (production-grade with connection pooling and proper indexing). The checkpointer writes every state transition keyed by thread_id and checkpoint_id, building an append-only history of the workflow.
Without a checkpointer, the graph is stateless across invocations. Every graph.invoke starts fresh. interrupt_before silently does nothing because there is no state to preserve and nowhere to resume from. This is the most common 'why is my interrupt not working' bug in newcomer LangGraph code.
Interrupt configuration. At compile time, pass interrupt_before=['executor'] (or interrupt_after=['planner']) to the compile call. The runtime treats the listed nodes as gated: execution stops at the boundary, the state is checkpointed, and control returns to the host.
interrupt_before vs interrupt_after is a small but important distinction. interrupt_before pauses just before the node runs, useful when you want the human to approve the proposed action before any side effects. interrupt_after pauses just after, useful when the human reviews the output and decides whether to continue or branch. For destructive shell commands, interrupt_before is almost always right.
The interrupt list is part of the graph contract. Treat it as a security boundary: the list defines which nodes run under agent authority and which run only with explicit human approval. Reviewers of the workflow code should be able to read the interrupt list and immediately understand where the trust boundary lies.
Situations where this technique stops working.
2–4 min · Everything important, quickly.
Real products, models, and research that use this idea.
- GitHub Copilot Workspace 2026 uses interrupt and approve for repository-modifying actions, with the checkpoint backing a multi-day editing session.
- Anthropic's published agent reference uses a LangGraph-style HIL pattern for any shell command that mutates the filesystem.
What an interviewer would ask next. Try answering before peeking at the approach.
QWhat changes if you need to support hundreds of concurrent human-pending workflows, not just a handful?
Move the checkpointer to a properly indexed Postgres with connection pooling. Add retention policy and a background sweeper for abandoned threads. The host needs a worker pool for the resume invocations, ideally with backpressure. UI side needs pagination over pending threads. Operationally similar to a job queue with extra state.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Trying to implement human approval by re-running the workflow from scratch after the human responds. Without a checkpointer, the resume burns tokens replaying everything, breaks idempotency for tools that already ran, and loses any conversational state from earlier hops.
60 second bullets to scan on the way to the call.
Why the checkpointer is structurally required, not optional
What interrupt_before and interrupt_after each enable
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.