LangGraph Memory: Checkpoints, Cross-Thread Stores, and Supermemory
Separate thread checkpoints from reusable user context, test both locally, and add Supermemory at an explicit retrieval boundary.

LangGraph has two useful persistence concepts: a checkpointer saves graph state for a thread, while a store can hold information shared across threads. Supermemory can supply an additional retrieval and memory-management service. It does not replace the need to decide which state belongs to a conversation, a user, or a business system.
A new thread can start with empty conversation history and still retrieve a known preference. That is the behavior to test. Describing every new thread as having no memory ignores LangGraph's native store support.
Check the native distinction first
The LangGraph persistence documentation describes checkpoints and stores separately. This small example uses the actual LangGraph APIs without an LLM or network request. Install langgraph in an isolated Python environment, then run it as a script.
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.store.memory import InMemoryStore
class State(TypedDict):
answer: str
store = InMemoryStore()
namespace = ("demo-tenant", "demo-user", "preferences")
store.put(namespace, "timezone", {"value": "Europe/London"})
def recall(state: State):
item = store.get(namespace, "timezone")
return {"answer": item.value["value"] if item else "unknown"}
builder = StateGraph(State)
builder.add_node("recall", recall)
builder.add_edge(START, "recall")
builder.add_edge("recall", END)
app = builder.compile(checkpointer=InMemorySaver(), store=store)
first = app.invoke({}, {"configurable": {"thread_id": "thread-a"}})
second = app.invoke({}, {"configurable": {"thread_id": "thread-b"}})
assert first["answer"] == second["answer"] == "Europe/London"
assert store.get(("other-tenant", "demo-user", "preferences"), "timezone") is None
The fixed namespace is deliberate for this demonstration. In a web application, derive it from authentication and pass it through an explicit per-request context. Never reuse a mutable global user identity across simultaneous requests.
Both backends here are in memory. They demonstrate thread versus user scope within one process, not persistence after a server restart. Choose a durable checkpointer and store for that requirement, then test restarts against those backends.
Where Supermemory fits in the graph
The documented Supermemory integration fetches user context before a model node and can save selected conversation content afterward. Keep these as visible stages:
| Stage | Required behavior |
|---|---|
| Resolve identity | Obtain an authorized tenant/user scope |
| Retrieve | Fetch a bounded amount of relevant background |
| Answer | Combine current messages with background marked as data |
| Persist | Save only the information your retention policy permits |
| Observe | Record IDs, status, and timing without dumping sensitive content |
A graph checkpoint records execution progress. A remote memory write is a separate side effect. If the graph retries or resumes after that write, the same content may be submitted twice unless your application uses a stable source ID and reconciliation path.
Keep write timing explicit
A durable checkpoint does not imply a newly ingested document is already searchable. Capture the remote document ID and processing state. If the next turn depends on the just-saved fact, carry the confirmed current-turn value in thread state while background processing finishes. Do not repeatedly search until a model happens to return the desired answer.
For background writes, a queue should survive a worker restart and distinguish retryable service failures from invalid input. The ingestion guide covers freshness and retry responsibilities.
Acceptance tests before a live rollout
Use two threads for the same fictional user and a third for another user. Confirm shared user context only reaches the authorized threads. Restart the process with your durable backend, replay a resumed node, correct a fact, and delete the source. Verify each step independently of final prose quality.
The local example establishes native API behavior and cross-thread lookup. It does not establish cloud ingestion, model recall, or production latency. Evaluate those using your chosen model, deployed checkpointer, corpus, and request load. Generic memory benchmark results are not measurements of this graph.
For the related implementation, see Conversational Memory in LangChain: History, Stores, and Retrieval.
Local API check: Python 3.12, langgraph 1.2.11. The test uses the in-process backends shown above.
To add external user context to your graph, get started with Supermemory and connect one retrieval step under an authorized user scope. Keep the LangGraph checkpointer responsible for thread state and test continuity across two threads.