Model setup recipes
Last updated
Save and resume a local LLM workflow with LangGraph
A checkpointer saves graph state for one thread. Fix the local model endpoint and thread_id to inspect and resume work after a pause.
This example uses ChatOllama in Python to call an Ollama model at http://127.0.0.1:11434, then stores input and response messages from a LangGraph StateGraph in checkpoints.sqlite with SqliteSaver. Reuse the same configurable.thread_id on each call to continue that thread. An in-memory checkpointer disappears when the process ends; choose SQLite when you need restart recovery.
To continue a local-LLM conversation after restarting a program, save its questions and answers. A LangGraph checkpoint records graph execution state. The example stores conversation messages in SQLite and restores them with the same conversation ID.
Separate the model call from graph-state storage
LangGraph represents processing steps as nodes and their connections as edges. Saving state in a checkpoint lets the next request resume with the same thread_id. Start here with one question-answering node and a local Ollama call.

Prepare a virtual environment and local model endpoint
Start Ollama and note the chat model ID you already downloaded. In a Python virtual environment1, install langgraph, langgraph-checkpoint-sqlite, and langchain-ollama. Set ChatOllama's base_url to the default server at http://127.0.0.1:11434 and use the model ID shown by ollama list.
python -m venv .venv
source .venv/bin/activate
python -m pip install -U langgraph langgraph-checkpoint-sqlite langchain-ollamaBuild a state graph that answers a question
Use MessagesState and StateGraph to define one node that answers a user question. Open a SQLite saver as a context manager to store checkpoints in checkpoints.sqlite, then attach the saver when compiling the graph. Pass {'configurable': {'thread_id': 'demo-1'}} to the first and later invocations to continue that thread's messages.
import sys
from langchain_ollama import ChatOllama
from langgraph.checkpoint.sqlite import SqliteSaver
from langgraph.graph import START, END, MessagesState, StateGraph
model = ChatOllama(model="YOUR_OLLAMA_MODEL_ID", base_url="http://127.0.0.1:11434")
def answer(state: MessagesState):
return {"messages": [model.invoke(state["messages"])]}
builder = StateGraph(MessagesState)
builder.add_node("answer", answer)
builder.add_edge(START, "answer")
builder.add_edge("answer", END)
config = {"configurable": {"thread_id": "demo-1"}}
mode = sys.argv[1]
with SqliteSaver.from_conn_string("checkpoints.sqlite") as checkpointer:
graph = builder.compile(checkpointer=checkpointer)
if mode == "start":
question = "예제 문서: 장비 대여 규정의 시행일은 2026년 4월 1일이다. 이 문서의 시행일은 언제야?"
graph.invoke({"messages": [("user", question)]}, config)
print("saved messages:", len(graph.get_state(config).values["messages"]))
elif mode == "resume":
print("restored messages:", len(graph.get_state(config).values["messages"]))
result = graph.invoke({"messages": [("user", "방금 답변에서 날짜만 다시 말해줘.")]}, config)
print("messages after follow-up:", len(graph.get_state(config).values["messages"]))
print(result["messages"][-1].content)
else:
raise SystemExit("Usage: python app.py start|resume")
Call twice and check state, then test restart recovery
Send an initial and follow-up question with the same thread_id, then inspect the length of graph.get_state(config).values['messages'] and the last reply. For a meaningful continuity check, do not manually resend the earlier conversation in the second question. After ending the process, reopen the same SQLite file with the same thread_id to load the saved state.
InMemorySaver suits an in-process check, but its state disappears when the process exits. If the SQLite file is not updated, check that the graph received the checkpointer and that each call uses the exact same thread_id. A different ID starts a separate conversation.
If several people continue the same conversation or you switch devices mid-thread, local checkpoints2 alone do not solve it. Compare a setup that keeps state on a server separately.

Terminology notes
Python virtual environment — An isolated space for installing Python packages per project, helping reduce package-version conflicts.
Back to the textCheckpoint — A file containing saved model weights and related state. Versions or tasks in one model family may use different checkpoints.
Back to the text
Frequently asked questions
- What should you check first in this article?
- This example uses `ChatOllama` in Python to call an Ollama model at `http://127.0.0.1:11434`, then stores input and response messages from a LangGraph `StateGraph` in `checkpoints.sqlite` with `SqliteSaver`. Reuse the same `configurable.thread_id` on each call to continue that thread. An in-memory checkpointer disappears when the process ends; choose SQLite when you need restart recovery.
Read next
read first
What Is a Local AI Agent? When It Makes Sense to Run One
Executable programs and extensions
Install Hermes Agent and Connect a Local Model: From Your First Task to Permission Checks
Model setup recipes
When OpenRouter Is Unavailable, How Do You Switch Your App to a Local LLM?
Model setup recipes
How to run Nemotron Bolt on an RTX 3090 or 5090
