Why an app-level gate cannot resume
HouseWarm’s review gate works and cannot be resumed, because nothing durable held the run — naming exactly what a checkpointer adds is what converts “I designed a review step” into “I wired a review step into an execution graph.”
You will be asked some version of this in the interview, and the sloppy answer is easy to give. “A graph lets you put a human in the loop.” You already put a human in the loop. HouseWarm holds every downstream step until a broker approves or corrects an extracted field, and the screen that does it is the strongest agentic UX on your résumé. Answer that way and you have described your existing product as though it were a new capability.
The precise answer is narrower and much stronger. What you gained is not the pause. It is where the pause lives. This lesson is about naming that difference exactly, including the parts where the app-level gate is genuinely fine and the graph costs you something.
What is actually holding the pause
Trace the two flows to the moment the broker walks away from their desk.
In HouseWarm, the extraction request completed. The model returned, your server wrote fields and confidences somewhere, and the response went back. The agent is not running. It is not suspended. It is finished. What is waiting is a record in your own application saying a human has not decided yet, plus a component rendering that record. The pause is a state in your product.
In a graph with a checkpointer, the run is suspended inside a node. The state that node was working with has been written to a store at the superstep boundary, under an identifier, and the process that resumes it does not need the original request, the original server, or the original browser. The pause is a state in the run.
Both sentences describe a review gate that works. Only one of them describes something that exists when nobody is looking at it.
The two definitions this rests on
LangChain’s checkpointers page defines the two nouns. A checkpoint is “a snapshot of the graph state saved at each super-step”, and a thread “contains the accumulated state of a sequence of runs.” The persistence page states what the pair is for:
“Use them for short-term, thread-scoped memory, including conversation continuity, human-in-the-loop workflows, time travel, and fault tolerance.” (LangChain, Persistence)
Four uses, one mechanism. That is the sentence to have memorised, and it is worth noticing that human-in-the-loop is listed beside fault tolerance rather than as its own feature. They are the same capability pointed at two different interruptions: a person taking an hour, and a process falling over. If you can restart from a checkpoint after a crash, you can restart from one after a lunch break.
Name the source honestly, as everywhere else in this course. LangChain writes this documentation and sells the hosted platform it leads to. Vendor documenting its own product. The definitions are mechanical and checkable; the surrounding framing is an argument for adoption. Nothing on either page mentions app-level approval gates, request/response applications, or HouseWarm. The comparison running through this lesson is this course’s own reasoning about its own prior product, built on top of the two definitions above rather than quoted from anyone.
Four consequences, each traced to the mechanism
This is the list to be able to give cold, with the cause attached to each item rather than the symptom:
- The run is addressable. A thread ID names it, so a second reviewer, a second tab, a mobile handoff or a background sweep for stalled work can all reach the same paused run. An app-level gate has a session, which names a browser.
- Resuming continues rather than restarts. Execution picks up from the checkpoint, so the work before the pause is not redone. A gate built on a finished request has nothing to continue from, so its only resume is a fresh call.
- A crash and a coffee break are the same event. The fault-tolerance case and the human-in-the-loop case are one mechanism, so recovery work you do for one covers the other.
- The pause survives the client. Closing the tab loses a view of the run, not the run. That is the one a product manager understands instantly, and it is downstream of the other three rather than being its own feature.
Every item on that list is the same primitive showing up four times. That is the shape of a good architecture answer: one cause, several visible effects, and no effect that cannot be traced back.
What it costs, and when the app-level gate is right
The honest version has a second half, and leaving it out is how people get caught.
A checkpointer is a store you now operate. In JavaScript the in-memory saver ships with LangGraph; anything durable is a separate install — SQLite, Postgres, MongoDB and Redis each have their own checkpoint package. That is a schema, a connection, a migration path and a backup story that your request/response gate did not need. This course does not print constructor code for the Postgres or SQLite savers because no page it could fetch showed one, and a guessed constructor is worse than none.
A checkpointer is also a durable copy of graph state. Every channel the state schema declares gets written at every superstep, which for a document product means the document’s contents can end up in the checkpoint store for as long as the thread lives, addressable by a single ID. That may be exactly what you want for an auditable review trail. It is still a decision, and it is a different conversation with whoever owns data retention. The showable-state lesson in the state-and-time module is where that gets designed rather than noticed.
So the app-level gate remains the right call for a product where the work before the pause is cheap to redo, the reviewer decides inside one session, and nothing else needs to address the run. Much of the software in a portfolio company looks like that. Recommending a checkpointer there is the mirror-image mistake to claiming you invented human-in-the-loop.
Retrieval check
Your review gate and a graph interrupt both stop work and wait for a person. State the difference in one sentence, then state what it costs — no more than two sentences total.
Check your answer
The pause is durable and belongs to the run rather than to the request, so the run is addressable by ID, resumes from its checkpoint instead of from the top, and outlives the client that started it. The cost is a checkpoint store you now operate and a durable copy of graph state that somebody has to make a retention decision about.
If your version of the first sentence contains the words “human in the loop” as the thing gained, rewrite it. You had that. Naming the durable pause as the gain, and the store as the price, is the answer that survives a follow-up.
Check your recall
Answer from memory — no scrolling back.
Hands on
Write the two-column version, then the ninety-second version
Done when: ARTIFACT.md has a table with one row per claim, a column for what the app-level gate does and one for what the checkpointed graph does, no row that is really a feature you never built — plus a spoken paragraph that names one cost of the checkpointer.
- In
learning/agent-graphs/ARTIFACT.mdunder Module 2, make a two-column table. Left column: what HouseWarm’s gate does today. Right column: what the same step does with a checkpointer under it. One row per claim. - Fill in the rows you can defend mechanically — who can address the run, what happens on resume, what happens when the process dies, what happens when the tab closes.
- Now audit your own table. Delete any row where the left column says “cannot” but the honest reason is that you never built it rather than that the architecture forbids it. A missing notification email is not evidence about durability.
- Add a Cost row. Name the store, and name the state that is now written durably at every superstep. If you cannot say which channel holds document contents, that is the row to bring to the showable-state lesson later in the course.
- Write the ninety-second spoken answer underneath. Structure: what the gate does today, the one-sentence difference, three consequences, one cost. Time yourself reading it out loud. If it runs long, the consequences are where it bloats.
- Bring the table and the paragraph into the chat. I will look for a row that is a feature rather than a mechanism, and for a spoken answer that quietly claims you invented human review.
What this does not cover
This lesson argued about where a pause lives. It said nothing about what the person on the other side of the pause is allowed to do. Approve is the easy verdict, correction is the one that decides whether your state schema was designed for it, and rejection is a third downstream path rather than a cancelled request. That is the decision-surface lesson in this module.
It also treated the paused node as safe to re-enter, which it is not automatically. When a run resumes, the node restarts from its first line, and where you put a side effect relative to the interrupt() call decides whether that is harmless or expensive. The mid-tool-call lesson is that rule and its mitigations.
The mechanics of the store itself — threads, checkpoint history, reading a snapshot to reconstruct where a user was, replaying versus forking — are the state-and-time module. Here the checkpointer was an argument, not an API.
Read this next — primary source
PersistenceLangChain — docs.langchain.com, JavaScript docs, fetched 2026-09-05. Vendor documenting its own product
A short overview page, and the one to read because it is short: it names the four things a checkpointer is for in a single sentence, then hands off to the checkpointers guide for detail. Read it for the list, and notice what the list does not claim. It says nothing about approval flows in general, nothing about request/response applications, and nothing comparative at all. The comparison this lesson makes is the course’s own, built on top of what the page states.
Stuck, curious, or think this lesson is wrong? Ask your teaching agent. The lessons are the scaffold; the conversation is where the learning gets unstuck.