Close a chat window, come back tomorrow, and ask a follow-up question. A good agent should not stare blankly at you. This article explains how AI agents maintain state across conversations: what they store outside the model, where that stored information lives, and how it is loaded, updated and retired when a new conversation starts. The short answer is that the model itself does not remember. Persistence is built around it, in session stores, checkpoints and memory stores, keyed to a stable conversation or user identity.
That distinction matters. Inside one conversation, an agent works from its context window: the current messages, tool outputs and reasoning steps in front of the model right now. Across conversations, the agent must write useful information out to a store that survives the end of the chat, find the right stored information when a later conversation begins, and use it without letting stale information take over.
What state means across conversations
State across conversations is not one thing. It is several kinds of information, each with a different lifetime and a different reason to keep it.
First, conversation history: what was said, decided and done in an earlier session. Second, user facts and preferences that should carry to the next conversation, such as a preferred format or a standing instruction. Third, task progress: a multi-step job started in one conversation and resumable in another, including which steps are done and which are open. Fourth, tool or system state: external facts already established, such as an order status checked or a file created.
The model’s active context is volatile by design: it is available during the session, but it is not itself the stored record. Cross-conversation state is the deliberate decision to keep selected information in an external store beyond that boundary, so that persisted history can be fetched into later turns even after the active context has ended.
How AI agents maintain state across conversations
The following ordered mechanism is a useful design model, illustrated by the frameworks discussed here, even though the names for the parts differ.
Step one is identity. The agent assigns a stable identifier to the conversation, to the user, or to both, and scopes stored state to it. In LangGraph, a thread_id in the graph configuration scopes a checkpoint to one conversation thread, while a user_id scopes durable data to one user across threads. Without that scoping, two conversations would bleed into each other, and two users could see each other’s state.
Step two is writing state out. At turn or task boundaries, the agent saves the state that matters instead of keeping it only in the prompt. LangGraph’s persistence documentation describes this as checkpointing: saving a thread’s graph state as a checkpoint so a conversation can be continued, resumed after an interruption, or recovered after a failure. The OpenAI Agents SDK describes a similar pattern for sessions: when a session is present, the runner automatically persists new user input and assistant output after each run completes.
Step three is loading and reconciling state. At the start of a new conversation, the agent fetches the stored state for that identity and merges it with the new conversation. The OpenAI Agents SDK, for instance, fetches previously stored conversation items and prepends them to the next turn. Reconciliation matters here: stored state may be incomplete, out of date, or contradicted by what the user says now. The agent should treat recalled state as a starting point to verify, not as a fact that overrides the current conversation.
Step four is updating and retiring state. As the conversation progresses, new information replaces or refines old information, and entries that are no longer true should be superseded or removed. An agent that only ever adds state will slowly accumulate a record that contradicts itself, so old checkpoints should be pruned and useless state should expire.
Session stores, checkpoints and summaries

Builders usually choose between three persistence mechanisms, and many systems combine them.
Session and conversation stores hold the history of a conversation so it can be reloaded. In the OpenAI Agents SDK, a session is the persistent memory layer for conversation history across runs: the documented behavior is that stored items are fetched before a turn and new items are persisted after it. Server-managed conversation continuation, via conversationId or previousResponseId, is a separate alternative strategy, not a session implementation, and the SDK documentation advises against mixing the two for the same history. In LangGraph, the checkpointer plays a comparable role for a single thread: it saves the graph state at each step, and passing the same thread_id later restores that state.
Checkpoints and snapshots are the mechanism for resumable work. A checkpoint is a saved snapshot of an agent’s state at a point in time, which makes it possible to continue a conversation, resume after an interruption, or recover from a failure. The practical difference from a plain history store is that a checkpoint captures task state, not just messages: where a multi-step job got to, and what remains.
Summaries and structured notes are the compact alternative when full history is too large to reload every time. Instead of storing every message, the agent distils each conversation into the facts, decisions and outcomes that a future conversation will actually need. This is also how episodic memory systems work in practice: summary filters distil lessons or user details into compact blocks, which are then retrieved when relevant.
Use a session or checkpoint store when the exact thread must be resumable, and a summary or structured note when only the conclusions matter. Use both when a system needs resumable threads and durable knowledge: LangGraph’s documentation notes that most applications can use both a checkpointer for the current thread and a store for durable information across threads.
One warning applies to all three: storage that lives only in memory does not survive a restart. LangGraph’s documentation states that MemorySaver and InMemorySaver store checkpoints in RAM, and that when the process restarts, all checkpoints are lost. For production use it points to PostgresSaver, and for local development to the file-based SqliteSaver.
Retrieval and memory stores for long-lived facts

Loading everything an agent has ever stored is neither affordable nor useful. The context window is finite, and a long history would crowd out the current task. So agents retrieve a subset of stored state at conversation start, guided by what the new conversation is about.
That retrieval works better when memory types are kept distinct. Working memory is the active context of the current session and may be discarded when the session ends, whereas externally persisted history can be fetched into later turns. Episodic memory is the record of past interactions: what was asked, what was answered and what happened. Semantic memory is the distilled, relatively stable knowledge about the user, the organisation or the domain. Mixing them causes predictable errors: a semantic question can return an irrelevant episode that merely resembles it, and an episodic question can return a semantically similar event from an unrelated conversation.
At the start of a new conversation, a retrieval layer typically selects records by recency, relevance and importance, may load stable user context as an optional application policy, when relevant and appropriate, and loads task state when an active task is detected. Retrieved state should be kept separate from what the user has just said and checked against the current conversation before the agent acts on it.
Two retrieval patterns are worth distinguishing. In a checkpoint or session pattern, the agent reloads the state of a specific thread, because the user is continuing that conversation. In a cross-thread pattern, it searches across past conversations for relevant facts, because the user is starting a new conversation but earlier facts still apply. Confusing the two is how an agent either forgets a resumable task or drags an unrelated conversation into a new one.
A practical design for cross-conversation state
A workable design can be described in four decisions, in order.
First, decide what is worth persisting before writing any storage code. Not every message deserves to survive. Persist decisions, preferences, task progress and verified facts. For curated long-term memories, be selective: do not carry over throwaway chatter, intermediate reasoning that has already produced a conclusion, or unconfirmed information as durable facts. That selective policy is distinct from session-history or checkpoint persistence, where the documented SDK session pattern persists new user input and assistant output after each run. A write policy, even a short written one, prevents the store from becoming a dump of everything the agent has ever seen.
Second, choose a storage layout keyed by user and conversation, with versioning. As a design example, a thread-scoped record can carry its user, its conversation, a timestamp, and a way to supersede it; a shared application record may instead be scoped to the application or domain, with the same timestamping and supersession. That makes scoping, expiry and correction possible later. In LangGraph terms, this is the discipline behind thread_id and user_id: the identifiers are lookup and scoping keys, not a substitute for separately enforced authorization.
Third, write, read and update state through a single narrow interface. If several parts of the system write directly to the store in different formats, the stored state risks drifting, and retrieval becomes harder to trust; consistent schemas or validation are design considerations for keeping it reliable. One interface also makes it possible to change the backing store, from a local file to a database, without rewriting the agent.
Fourth, test resumption explicitly. Close a conversation, reopen it, and check continuity: does the agent remember the decision, resume the task, and avoid re-asking settled questions? Then test the harder cases: facts changed since the last conversation, a task resumed after a failure, and a new conversation that should not inherit an old thread’s state. Testing only inside a single running process hides the in-memory trap until deployment.
The following fragments illustrate the identity pattern. The first is an illustrative fragment, not a complete program; the second is clearly labeled conceptual pseudocode showing only the documented session behavior, not a verified SDK implementation.
# LangGraph: the same thread_id resumes the same conversation
config = {"configurable": {"thread_id": "support-case-42"}}
# Compile the graph with a checkpointer, then invoke with this config.
# A later invoke with the same thread_id loads the saved checkpoint.
# OpenAI Agents SDK: conceptual pseudocode, not a verified API example
# session = a persistent session object
# Pass the same session to each run; the SDK fetches stored items
# before the turn and persists new items after it.Note what the fragments have in common: the identifier is one part of persistence, not the whole mechanism. Changing an identifier, on its own, does not start a usable new conversation unless a store is configured; reusing it continues the old conversation only when the corresponding saved state survives in a configured backend. That is why identifier design, including keeping LangGraph’s PostgresSaver thread_id under 255 characters, belongs in the design rather than being left to chance.
Limits, mistakes and privacy trade-offs
Persistent state fails in ways that in-conversation context does not, and the failure modes should shape the design.
Stale and contradictory state is a documented failure mode. A user changes their mind, a project is renamed, or a task is completed elsewhere, and the stored record still says otherwise. When that record is treated as authoritative, the agent confidently acts on old information. Timestamping and versioning help, but the deeper defence is verification: confirm consequential recalled facts rather than silently acting on them. Episodic memory carries a sharper version, sometimes called compounding error: a flawed summary written in one conversation is retrieved as authority in the next.
Cost is the second failure mode. Checkpoints accumulate over long conversations, and LangGraph’s documentation warns that this can increase latency and storage costs, advising periodic pruning or a retention policy. Loading too much history has the same effect in token terms: every recalled message consumes context that the current task needs. Summaries and structured facts exist precisely to keep that cost bounded.
Privacy and retention are the third trade-off. State stored between conversations is a record about a person or an organisation, and it needs a retention rule: what expires, what the user can delete, and what should never be stored at all. Sensitive information seen in one conversation should not silently become permanent knowledge in the next, and memory must be isolated under an access policy appropriate to its scope — per-user where it belongs to one user, and governed as shared application knowledge where it is shared — so that one user’s private state is never loaded into another user’s conversation.
The common mistakes follow directly from these limits. Persisting everything indiscriminately into curated long-term memory, instead of deciding what is worth keeping there — which is distinct from full session-history or checkpoint persistence, where a thread’s history may legitimately be recorded in full. Conflating sessions, by reusing an identifier across conversations that should be separate, or by loading cross-thread facts into a thread that should stand alone. Trusting recalled state without verification, especially for actions with real consequences. And testing only in a single process, so that in-memory persistence looks durable until the first restart.
Done well, cross-conversation state is unremarkable to the user, which is the point. The agent picks up where the last conversation left off and resumes the interrupted task, without re-asking and without leaking one conversation into another. That continuity does not come from the model remembering. It comes from a deliberately designed store, a stable identity, a write policy, and a retrieval layer that loads only what the new conversation needs.












