Short answer: Cross-session memory spans separate visits over time. Cross-conversation memory spans separate threads that may run in parallel.
A session is usually one sitting or login stretch. A conversation is one thread of dialogue. They are not the same boundary. Mixing them up breaks scoping: either memories leak across the wrong threads, or returning users lose continuity they should keep.
Tool-use memory was about an agent’s competence with its own mechanics. Zooming back out to a more structural question, there’s a distinction worth making precise before it causes confusion: a “session” and a “conversation” sound like they mean the same thing, and in casual conversation about memory systems they often get used interchangeably, but they’re not actually the same boundary, and conflating them leads to scoping decisions that don’t match what a system is really trying to isolate.
What’s the Actual Difference Between a Session and a Conversation?
A conversation is a topical thread, a continuous exchange about one subject or task, from its start to whatever counts as its natural end. A session is a technical unit tied to how someone is actually connected to a system, typically bounded by logging in and logging out, or by an app being opened and later closed. These two boundaries frequently line up, a person opens an app, has one conversation, and closes it, which is exactly why it’s easy to assume they’re the same thing.
They stop lining up the moment usage gets even slightly more realistic. A single conversation can span multiple sessions if someone starts a task, closes the app, and reopens it later to continue exactly where they left off. A single session can just as easily contain several unrelated conversations, someone opening an app once and asking about three completely different things in a row before closing it again. Neither boundary is a subset of the other, they’re measuring different things entirely.
Why Does This Distinction Actually Matter for How Memory Gets Scoped?
It matters because the two boundaries answer different questions, and a memory system that only tracks one of them can’t answer the other. Cross-conversation memory answers “does this fact or context carry over into a new, topically separate conversation,” regardless of whether any login or logout happened in between. Cross-session memory answers “does this fact or context survive a person closing and reopening the app,” regardless of whether the conversation itself is continuing the same thread or starting something new.
A system that assumes these are identical will get confused exactly at the point where they diverge. If a conversation about one topic gets interrupted by a session boundary and picks back up later, a system relying purely on session boundaries to decide when a “fresh start” has happened might wrongly discard context that the conversation itself never actually finished needing.
What Actually Goes Wrong When a System Conflates the Two?
Treating every new session as automatically meaning a new conversation causes a system to lose the thread of something genuinely still in progress, forcing a person to re-explain context they already gave, just because they happened to close and reopen the app in between. This is a subtly worse failure than ordinary statelessness, because it looks like the system should have remembered, the conversation never actually ended, and yet it behaves as if it did.
The opposite mistake, treating everything within one session as automatically part of the same conversation, causes unrelated topics to bleed into each other. A person who asks about one unrelated thing right after finishing a different task within the same session might have that earlier, now-irrelevant context inappropriately dragged into the new topic, simply because no session boundary happened to separate them, even though the conversational thread genuinely did change.
How Should a System Decide Which Boundary Actually Matters for a Given Piece of Memory?
The right question to ask is what’s actually supposed to persist and what’s actually supposed to reset, independent of the technical mechanics of login and logout. A conversation-scoped running summary should genuinely persist across a session boundary if the same topical thread is picking back up, and it should genuinely reset once a new, unrelated topic starts, even within an unbroken session. A user-level fact, someone’s stated preference or general context, shouldn’t be tied to either boundary at all, it should simply follow the person regardless of how conversations or sessions happen to be chopped up around them.
How Does Weaviate Engram Let These Two Boundaries Be Tracked Independently?
Weaviate Engram doesn’t hardcode a single notion of “session,” it lets an application pass its own `conversation_id` as a custom scope property, entirely independent of whatever session mechanics the application itself uses to manage logins. This means a conversation can span as many sessions as it needs to, and a session can contain as many distinct conversations as actually happen within it, without the memory layer forcing one to determine the other. Consider a grant-writing assistant helping nonprofit staff draft applications across multiple funding cycles, where a single application draft might get worked on across several separate login sessions over multiple days:
from engram import EngramClient
client = EngramClient(api_key=os.environ["ENGRAM_API_KEY"])
client.memories.add(
[
{"role": "user", "content": "We're applying to the Hargrove Foundation's education grant, deadline is in three weeks."},
{"role": "assistant", "content": "Let's start with the needs statement. What specific gap is this program addressing?"},
],
user_id="staffer-8820",
properties={"conversation_id": "hargrove-application-2026"},
)
Two days later, after the staff member has logged out and back in at least once, they resume work on the same application, and this new session’s messages are still tagged with the same `conversation_id`, so the conversation’s running context continues exactly where it left off, regardless of how many sessions came between:
summary = client.memories.search(
query="conversation summary",
user_id="staffer-8820",
properties={"conversation_id": "hargrove-application-2026"},
topics=["ConversationSummary"],
retrieval_config=FetchRetrieval(limit=1),
)
Later that same day, still within the same login session, the staffer starts drafting an entirely unrelated application to a different funder, and this new work gets tagged with its own distinct `conversation_id`, so it starts with a clean slate rather than inheriting the Hargrove application’s context just because no session boundary happened to separate the two tasks. The two dimensions, which session a message technically arrived in, and which conversation it topically belongs to, are tracked completely independently, letting each one persist or reset exactly according to what it’s actually supposed to represent.
Cross-session and cross-conversation memory are both about text-based context surviving across some boundary. A different challenge entirely comes from content that was never text in the first place, images, audio, or other non-text data that a memory system still needs to be able to capture and retrieve meaningfully. Our next chapter, What is multi-modal memory?, turns to exactly that challenge.