What is the difference between single-turn, multi-turn, and multi-session systems?

Short answer: Single-turn answers one request. Multi-turn keeps a conversation going. Multi-session must recognize a returning user across visits.

Each shape needs a different memory job. Single-turn often needs little beyond the current request. Multi-turn needs working continuity inside a sitting. Multi-session needs durable memory so the agent does not reset weeks later.

Not every agent or chatbot is solving the same problem, even when they look similar from the outside. A system that answers one isolated question, a system that handles a flowing back-and-forth conversation, and a system that’s expected to recognize a returning user weeks later are three genuinely different shapes of interaction, and each one has a different answer to the question of what memory actually needs to do. Treating all three the same, usually by assuming whatever works for the middle case will scale down or up to the other two, is exactly how systems end up either overbuilt for something simple or quietly broken the moment someone comes back after the session has ended.

What Actually Counts as a Single-Turn System?

A single-turn system answers one question and is done. A translation request, a calculator-style query, a one-off lookup, nothing about these expects or benefits from continuation. There’s no follow-up to anticipate and nothing worth carrying forward, because the interaction is complete the moment a response is given.

This matters because it means memory, in any form, genuinely isn’t a requirement here. The context window holds everything relevant to the one request being handled, and that’s the entire scope of what needs to be true. Building persistence into a system that only ever does this would be solving a problem that doesn’t exist yet, adding real complexity for a capability nothing in the interaction actually calls for.

What Changes the Moment a System Needs to Handle Multi-Turn Conversation?

The moment a follow-up question can reference something said earlier in the same sitting, like asking for wind speed statistics and then, in the next message, asking “and what about the temperature?” without repeating the original context, the system needs access to what came before within that same session. This is handled by keeping a running list of messages and passing the whole thing back on each new turn, so the model can see the earlier exchange when answering the follow-up.

This is genuinely sufficient for multi-turn conversation, and it’s worth being clear about why: everything relevant is still contained inside one bounded session. The message list might grow, and the cost of resending it grows along with it, but nothing about the problem requires surviving past the point where this particular session ends. The test that separates single-turn from multi-turn is simple: does a later message in this same sitting need to reference an earlier one? If yes, multi-turn handling is required. If the session ends and nobody expects anything to carry forward, nothing more than that is needed either.

Why Does a Session Boundary Change Everything?

The moment a user closes the app, comes back the next day, or restarts an entirely new session, and still expects the system to know something from before, everything about the multi-turn solution stops applying. There’s no message list to resend, because that list existed only for the lifetime of a session that’s already over. Nothing about extending or better-managing that in-session list solves this, because the list itself no longer exists once the session ends.

A concrete example makes this obvious. In one session, a user mentions they’ve just moved to Berlin and prefer specialty coffee over chains. They close the app. In a new session, days later, they ask for a coffee recommendation, expecting the system to already know their location and preference without repeating either. Nothing about the first session’s message history is available to reference here, because that history lived and died with the session it belonged to. Whatever’s going to answer this new question correctly has to come from somewhere that survives independently of any single session’s lifetime, which is a fundamentally different kind of mechanism than a growing list of messages.

Is Multi-Session Just Multi-Turn With the History Saved to Disk?

It’s tempting to think the fix is simple: just save the message list somewhere durable and reload it the next time the same user shows up. This reintroduces the exact problems already covered for a single long session, except now at a much larger scale, because instead of one sitting’s worth of history, there could be months or years of accumulated transcripts to reload and resend. The cost and latency problems get worse, not better, and whatever gets buried in the middle of that much history is even less likely to actually get used by the model, since the amount of irrelevant material stacked around any one useful detail keeps growing indefinitely.

What multi-session interaction actually needs is the extraction-and-retrieval approach covered earlier, not a bigger version of the same message-passing trick. Facts worth keeping need to be pulled out, reconciled against what’s already known, and made searchable, so a new session can retrieve only what’s relevant rather than reloading everything that’s ever happened. Multi-session also introduces a requirement multi-turn never had to deal with: identity that outlives any single session. Once a returning user is being recognized across separate sittings, whatever’s stored has to be scoped to that user specifically, not to a session that no longer exists by the time they come back.

How Does Weaviate Engram Handle the Jump From Multi-Turn to Multi-Session?

Weaviate Engram is built around exactly this distinction: ordinary message history handles what’s needed within one session, while Engram handles what needs to survive across separate ones, scoped to a user rather than to any particular sitting. Picture a home-improvement advice app where someone works through one project over a single evening, then comes back weeks later for a completely different project. Within that first evening, normal multi-turn message passing is all that’s needed. Once the session ends, what’s worth keeping gets captured separately:

from engram import EngramClient

client = EngramClient(api_key=os.environ["ENGRAM_API_KEY"])

client.memories.add(
    [
        {"role": "user", "content": "I've never really used power tools before, and I only have a basic drill."},
        {"role": "assistant", "content": "Good to know — I'll stick to drill-only projects and explain steps in more detail."},
    ],
    user_id="homeowner-2217",
)

Weeks later, in a completely new session about an unrelated project, that context is still available on request, without needing anything from the earlier session’s message history:

results = client.memories.search(
    query="What's this user's tool access and experience level?",
    user_id="homeowner-2217",
)

The scoping here is what makes this genuinely different from multi-turn handling rather than a bigger version of it: the memory is tied to the user, not to a session, so it’s exactly as available whether the gap between visits is five minutes or five months. That’s the actual architectural line between the two: multi-turn is solved by extending what happens inside a session, and multi-session is only solved by building something that was never bound to a session’s lifetime in the first place.

None of these three shapes says anything yet about what it actually takes to make an agent feel personalized, in the sense of adapting its behavior specifically to one person rather than just recalling facts about them on request. Our next chapter, What does personalization actually require?, picks up exactly that question, starting from the multi-session foundation this chapter has just laid out.