Skip to content

LangGraph interview questions that test production judgment

  • Lesson
  • Intermediate
  • 18 min read
  • Checked 15 Aug 2026

There is no reliable public ranking of LangGraph interview frequency. These questions cover the concepts in the current official API and the failure modes that reveal whether someone has operated a stateful workflow.

State → Node → Partial state update → Reducer → Edge decision → Next node

For a support system:

classify_question
billing ─────→ billing_specialist
technical ───→ technical_specialist
review_answer
END or bounded retry

State is the shared snapshot. Nodes do work and return updates. Reducers decide how each updated field combines with its current value. Edges choose what runs next.1

# Interview question A strong answer should include
1 What is LangGraph, and why use it? A low-level orchestration runtime for long-running, stateful workflows; persistence, branching, loops, streaming, and human review
2 LangChain versus LangGraph? LangChain supplies model, tool, and agent abstractions; LangGraph controls stateful execution. LangGraph can run without LangChain
3 Explain state, nodes, and edges. State holds the snapshot; nodes perform work and return updates; edges choose the next node
4 What is a reducer? A per-field function that combines the current value with a node’s update; the default replaces the old value
5 Why return partial state updates? A node normally changes only the fields it owns; reducers apply those updates to the accumulated state
6 Conditional edge versus Command? A conditional edge routes after a node; Command can combine a state update and a destination in one node return
7 What is a checkpointer? Persistence that saves thread-scoped state snapshots at execution steps
8 Thread, checkpoint, and store? A thread identifies one history; a checkpoint is one saved snapshot; a store holds application data across threads
9 How does human review work? interrupt() pauses through persistence; resume the same thread_id with Command(resume=...)
10 What happens on resume? The interrupted node starts from its beginning, so code before interrupt() runs again
11 How do you retry a failed node? Retry only classified transient failures; bound attempts and backoff; make repeated side effects safe
12 How do you stop an infinite loop? A terminal state, business budgets, tool/model budgets, escalation, and a recursion_limit backstop
13 How do parallel branches execute? Nodes in one super-step can run concurrently; reducers must combine simultaneous writes safely
14 What is Send for? Runtime-created fan-out, such as one worker per retrieved document, followed by reduction
15 When should you use a subgraph? A reusable workflow, specialist agent, or state boundary that can be tested and operated separately
16 How do you implement memory? Thread-scoped state through checkpoints; cross-thread application memory through a store
17 How do you stream execution? Choose the view: state updates, full values, model messages, custom progress, tasks, checkpoints, or debug data
18 How do you test a graph? Nodes, reducers, routes, partial paths, retries, interrupts, side effects, and complete trajectories

Four scenario answers interviewers remember

Section titled “Four scenario answers interviewers remember”

1. The payment succeeded, then the process crashed

Section titled “1. The payment succeeded, then the process crashed”

The recovery path may execute the node again. The payment call needs a stable idempotency key, such as the application’s payment_id. The provider must return the first result when it sees that key again. A checkpoint records graph progress; it cannot undo an external charge.

2. The side effect happens before approval

Section titled “2. The side effect happens before approval”

This ordering is dangerous:

charge_customer()
approved = interrupt("Approve charge?")

On resume, the node restarts and calls charge_customer() again. Ask for approval first, then perform the charge in a separate node. Keep the charge idempotent as a second line of defense.2

src/examples/langgraph/approval_payment.py
"""A LangGraph approval flow that keeps the payment side effect after interrupt()."""
from typing import TypedDict
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import END, START, StateGraph
from langgraph.types import Command, interrupt
class PaymentState(TypedDict):
payment_id: str
amount_cents: int
approved: bool
receipt_id: str
class PaymentGateway:
"""A tiny idempotent stand-in for a real payment API."""
def __init__(self) -> None:
self.receipts_by_key: dict[str, str] = {}
def charge(self, amount_cents: int, idempotency_key: str) -> str:
if idempotency_key not in self.receipts_by_key:
self.receipts_by_key[idempotency_key] = f"receipt-{len(self.receipts_by_key) + 1}"
return self.receipts_by_key[idempotency_key]
gateway = PaymentGateway()
def request_approval(state: PaymentState) -> dict:
decision = interrupt(
{
"question": "Approve this payment?",
"payment_id": state["payment_id"],
"amount_cents": state["amount_cents"],
}
)
return {"approved": bool(decision)}
def charge_after_approval(state: PaymentState) -> dict:
if not state["approved"]:
return {"receipt_id": "not-charged"}
receipt_id = gateway.charge(
amount_cents=state["amount_cents"],
idempotency_key=state["payment_id"],
)
return {"receipt_id": receipt_id}
builder = StateGraph(PaymentState)
builder.add_node("request_approval", request_approval)
builder.add_node("charge_after_approval", charge_after_approval)
builder.add_edge(START, "request_approval")
builder.add_edge("request_approval", "charge_after_approval")
builder.add_edge("charge_after_approval", END)
graph = builder.compile(checkpointer=InMemorySaver())
config = {"configurable": {"thread_id": "payment-pay-1042"}}
paused = graph.invoke(
{
"payment_id": "pay-1042",
"amount_cents": 4500,
"approved": False,
"receipt_id": "",
},
config,
)
finished = graph.invoke(Command(resume=True), config)
assert paused["__interrupt__"]
assert finished["receipt_id"] == "receipt-1"
assert gateway.charge(4500, "pay-1042") == "receipt-1"

3. Two parallel nodes write to the same list

Section titled “3. Two parallel nodes write to the same list”

Without a suitable reducer, the writes conflict or replace one another. Define the merge rule in the state schema:

import operator
from typing import Annotated
from typing_extensions import TypedDict
class ResearchState(TypedDict):
findings: Annotated[list[str], operator.add]

The reducer is part of the data contract. operator.add preserves both lists, but it does not remove duplicates or guarantee a business-specific order.

Do not rely only on a high recursion limit. The current runtime limit counts super-steps and raises GraphRecursionError when exhausted.3 Add a smaller product budget, such as five tool rounds or a cost ceiling, route to a final-answer or escalation node as the budget approaches, and retain the runtime limit as a backstop.

Failure Response
Network interruption or upstream 5xx Bounded RetryPolicy on the node
Invalid model-generated tool arguments Return structured failure so the model can correct within a loop budget
Permission denial Stop; a retry cannot grant access
Payment or email may already have succeeded Check idempotency key or remote result before repeating
Unknown programming error Bubble, trace, alert, and fix

RetryPolicy re-runs a node attempt. It should see only exceptions that are safe to retry. If a node catches every exception and converts it to a normal result, the policy has no failure to classify.4

  1. Node: Given this state, does the node return the expected partial update?
  2. Reducer: Given concurrent updates, does the combined state match the contract?
  3. Route: Does every important state choose the intended edge or Command destination?
  4. Pause: Does the graph expose the expected interrupt and resume only on the same thread?
  5. Failure: Which exceptions retry, how many attempts occur, and what happens after exhaustion?
  6. Trajectory: Did the graph call the allowed tools in a valid order and stop within budget?
  7. Side effect: Does replay with the same idempotency key create exactly one external result?

Compile a fresh graph and checkpointer for isolated tests. Test individual nodes, then partial paths, then the complete workflow.5

Use a direct model call or plain Python for:

input → model → output

LangGraph earns its place when execution must branch, loop, fan out, persist, pause, resume, recover, or expose its state transitions. A framework should follow the workflow’s needs, not create them.

LangGraph is a stateful orchestration runtime. I define typed state, nodes that return partial updates, reducers that merge those updates, and edges that control execution. A checkpointer saves thread-scoped snapshots for recovery and human review, while a store holds data across threads. I keep side effects idempotent because retries and interrupt resumes can execute node code again. I use LangGraph for branching, loops, durable execution, or approval—not for a simple model call.

Continue with the concept notes on state schemas, reducers, persistence, interrupts, retries, and Send.

  1. LangChain, Graph API overview.

  2. LangChain, Interrupts.

  3. LangChain, Graph API — recursion limit.

  4. LangChain, Fault tolerance.

  5. LangChain, Test.