Articles
LangGraph Interview Questions 2026: State, Checkpointing, Human-in-the-Loop, and Recovery
LangGraph Interview Questions 2026: state, reducers, checkpointing, HITL interrupts, durable execution, replay, and failure recovery.
LangGraph interview questions in 2026 increasingly test whether you can make an agent workflow stateful, interruptible, durable, and recoverable. Memorizing a few graph calls is not enough: interviewers want to see how you define state, combine concurrent updates, persist progress, approve risky actions, and recover after a worker or dependency fails.
The exact prompt will vary, but the reasoning pattern is stable: make state explicit, make side effects safe to retry, and explain what the system can prove after a crash.
What LangGraph Interviewers Are Testing
LangGraph is a low-level orchestration layer for long-running, stateful agent workflows. The official documentation centers on graphs, state schemas, persistence, interrupts, durable execution, and replay. A strong interview answer connects those features to engineering properties: deterministic transitions, bounded retries, idempotent side effects, observability, and a clear recovery point.
Expect questions in four clusters:
- State and graph control: How do typed state, reducers, nodes, edges, conditional routing,
Send, andCommandwork together? - Durability: What is a thread, when is a checkpoint written, and what changes when durability is
sync,async, orexit? - Human approval: How does
interrupt()pause a run, how is it resumed, and what must be safe if the node runs again? - Failure recovery: How do you inspect history, replay from a checkpoint, handle partial writes, and avoid charging or mutating an external system twice?
The article-specific thesis is simple: a LangGraph design is production-ready only when its state transitions and side effects remain understandable under pause, retry, replay, and partial failure.
State Schemas and Reducers
The graph state is the contract shared by nodes. In the Graph API, a schema can be expressed with a TypedDict, dataclass, or Pydantic model. Each key has a default update rule: a new value replaces the old value unless the key declares a reducer that combines updates.
That distinction is a common interview trap. A message list may need an append reducer, while a status field should usually use last-write-wins. If two parallel branches update the same key, the reducer defines how those updates are combined; it is not safe to assume that list order or execution order is accidental and therefore stable.
Be ready to explain:
- Which fields are inputs, working state, and outputs?
- Which invariants must hold after every super-step?
- What happens when two branches write the same key?
- How will a schema change be migrated for old checkpoints?
- Which fields are user-visible and which are internal bookkeeping?
For example, a reducer for an event log should be associative and deterministic enough that replay produces the same logical result. A counter updated by independent branches needs a reducer with an explicit merge rule; silently overwriting one branch is a correctness bug.
Nodes, Edges, Send, and Command
Nodes read state and return updates. Edges choose the next node, either directly or conditionally. StateGraph validates the graph and produces a compiled runnable; compilation is where you should catch missing destinations and structural mistakes before a request reaches production.
Conditional fan-out is useful for map-reduce work. Send can route a separate state payload to a worker for each item, while a reducer combines the results. In an interview, name the fan-out limit, the aggregation rule, and what happens when one worker fails. “Run them in parallel” is not a complete design.
Command is the control-plane escape hatch: a node can return a state update and choose the next destination in one value. It is also used to resume an interrupted run and, where appropriate, to navigate across a subgraph boundary. Keep the update and routing decision explicit so a reviewer can reason about state changes separately from control flow.
Checkpoints, Threads, and Durability
LangGraph persistence is organized around a thread and a sequence of checkpoints. A thread_id in the configurable input identifies the execution history. The checkpointer saves graph state at super-step boundaries, which lets the runtime resume a thread, inspect prior state, or create a new branch from an earlier point.
The official durability modes express a write-versus-latency trade-off:
| Mode | What it prioritizes | Interview trade-off |
|---|---|---|
sync | Finish the checkpoint write before the next step | Stronger crash boundary; more latency |
async | Start the write and continue execution | Lower latency; a crash can lose the newest pending write |
exit | Persist when the run exits | Lowest per-step overhead; weakest mid-run recovery |
Use InMemorySaver for a short test or demonstration. For production, choose a durable checkpointer appropriate to the deployment, such as a Postgres-backed saver, and explain retention, encryption, migrations, connection limits, and tenant isolation. A database checkpointer does not make external side effects transactional; it only records the graph's state and metadata.
One useful nuance is pending writes. If parallel tasks finish unevenly and one fails, a checkpointer may retain successful task writes so a retry does not repeat work that already completed. Your design still needs idempotency keys for calls outside the checkpointer, because an API charge, email, or ticket mutation cannot be rolled back by restoring graph state.
Human-in-the-Loop with interrupt()
An interrupt pauses execution and saves the current state so a person or another service can decide what happens next. A checkpointer is required. The caller resumes the same thread with a Command(resume=...) value; the resumed node can validate, approve, reject, or modify the proposed action.
The important safety rule is that code before an interrupt may run again when the node is resumed. The official guidance therefore recommends moving non-idempotent work after the interrupt or protecting it with an idempotency key. Do not place an interrupt inside a broad try/except that turns the pause into an ordinary error, and do not change the order of multiple interrupts between runs: their position is part of the resume protocol.
A concise approval flow sounds like this in an interview:
def approve_refund(state):
decision = interrupt({"action": "refund", "amount": state["amount"]})
if decision != "approve":
return {"status": "rejected"}
return charge_refund_once(state["order_id"], state["amount"])
The production version would make charge_refund_once idempotent, authorize the approver, record the decision, and expose an audit trail. The point is not the exact Python syntax; it is the boundary between asking for approval and performing the side effect.
Replay, Time Travel, and Recovery
Persistence gives you more than a resume button. get_state reads a thread's latest state, get_state_history exposes earlier checkpoints, and replay can rerun steps after a selected checkpoint. update_state can create a new checkpoint or fork a thread for a corrected input, which is useful for debugging and controlled “what if” analysis.
Separate these terms in an interview:
- Resume: continue an interrupted execution with new input.
- Replay: rerun deterministic graph steps from a recorded checkpoint.
- Fork or time travel: start a new branch from an earlier state without rewriting history.
- Retry: repeat work after a transient failure, with idempotency protection around side effects.
Recovery design should identify the last durable boundary, the state that can be reconstructed, and the external operations that need reconciliation. If a tool call timed out after the provider accepted it, a blind retry can duplicate the action. Use a request key, query the provider for the result, or route the action through an outbox or task table that has its own deduplication rule.
Tool Execution and Failure Boundaries
Treat tools as untrusted, failure-prone dependencies. Define typed inputs and outputs, enforce authorization, set timeouts, cap retries, and classify errors as retryable or terminal. A reducer should not hide an error by appending a success-looking message, and a node should not mark a task complete before the external operation is durably acknowledged.
Explain where you would put:
- request and idempotency keys;
- rate limits, circuit breakers, and backoff;
- human approval for destructive or expensive actions;
- redaction and access control for checkpoint contents;
- traces that include
thread_id, checkpoint ID, node name, and attempt number; and - a dead-letter or operator path for work that cannot be retried safely.
This is where a LangGraph answer becomes a systems answer. The graph controls orchestration, while your surrounding service owns authentication, tenancy, secrets, quotas, monitoring, and reconciliation.
A System-Design Prompt to Practice
Prompt: Design a support agent that reads a ticket, gathers account context, drafts a response, asks a human to approve refunds, and recovers after a worker restart.
Start with a typed state containing ticket ID, customer context, draft, approval decision, tool results, error status, and audit metadata. Use a thread per ticket. Persist after each meaningful super-step, interrupt before the refund, and resume with an approval command. Put the refund behind an idempotency key and record the provider's result before moving to the response-sent state.
Then discuss the hard cases: two workers update the same ticket, the approval expires, the refund provider times out, the checkpoint store is unavailable, or a prompt/schema version changes while old threads are still open. A high-quality answer names the invariant and recovery action for each case instead of adding components without a failure reason.
Five-Day Preparation Plan
| Day | Focus | Deliverable |
|---|---|---|
| Day 1 | State and reducers | Sketch a schema, three invariants, and one concurrent-update example |
| Day 2 | Graph control | Explain conditional edges, Send, Command, and a map-reduce failure |
| Day 3 | Persistence | Compare threads, checkpoints, durability modes, and a production saver |
| Day 4 | Interrupts and recovery | Design approval, idempotent tools, replay, retry, and reconciliation |
| Day 5 | Mock system design | Present the support-agent prompt and defend every failure boundary |
Frequently Asked Questions
What is LangGraph in an interview context?
LangGraph is an orchestration framework for stateful, graph-shaped agent workflows. Interviewers usually care less about memorizing helpers than about state ownership, deterministic transitions, persistence, approval boundaries, and recovery behavior.
What is the difference between a checkpoint and memory?
A checkpoint is a persisted snapshot of graph execution for a thread and super-step. Memory is a broader product or application concept that may include conversation history, retrieved facts, or user preferences. A checkpoint can support memory, but it is also an execution and recovery boundary.
Which checkpointer should I use in production?
Use a durable, operationally supported saver that matches your storage and availability requirements. The official examples use an in-memory saver for tests and show persistent options such as Postgres-backed savers for deployed systems. Explain retention, access control, migrations, and connection management rather than naming a database without a reason.
How does human-in-the-loop work?
The graph calls interrupt(), the checkpointer saves state, and an external actor resumes the same thread with a decision. Code around the interrupt must be safe if the node is entered again, especially when the approved action has side effects.
Is replay the same as retry?
No. Replay reruns graph logic from a known checkpoint, while retry repeats failed work. Both need deterministic code and idempotent side effects, but a retry usually targets an attempt and replay targets a historical execution point.
When should I choose sync over async durability?
Choose sync when losing the most recent step would violate a correctness or audit requirement. Choose async when the latency benefit is material and the application can tolerate redoing or reconciling a small amount of work. State the failure trade-off explicitly.
Final Takeaway
Prepare for LangGraph interview questions by telling one coherent reliability story: typed state makes the contract visible, reducers make concurrency explicit, checkpoints make progress durable, interrupts create a safe approval boundary, and idempotent tools make retries and replay survivable. Pair that explanation with a small system design and a concrete failure walkthrough.
Your strongest answer will show what the workflow can prove after a pause, a duplicate delivery, or a worker crash.
Sources and Further Reading
- LangGraph Graph API
- LangGraph persistence and checkpoints
- LangGraph interrupts
- LangGraph functional API and durable execution
- LangGraph time travel
- LangGraph subgraphs
- LangGraph checkpointer durability modes
- LangChain human-in-the-loop middleware
- LangGraph official repository
- Production incident-response agent discussion
Research note: Official LangGraph and LangChain documentation, the official repository, and a dated secondary practitioner discussion were checked on September 5, 2026. APIs and operational guidance can change; verify the version used in your interview or project.