Concepts

Browse docs

Core Concepts

Tap to expand

Contribute

ConceptsUpdated 2026-03-18

Memory Model

Understand what RetainDB stores, how scope works, and why user, session, and project boundaries matter more than any single endpoint.

The easiest way to misunderstand RetainDB is to think of memory as one flat list of facts.

It is not.

RetainDB memory only makes sense when you look at two things together:

  • the scope the memory belongs to
  • the kind of memory the system extracted or stored

Scope comes first

Before you think about memory type, think about where the memory lives.

Project scope

Every memory belongs to a project. Project is the top-level boundary for retrieval, sources, and tenancy.

If the project is wrong, nothing else matters. This is the most common first-integration mistake.

User scope

User-scoped memory is the long-lived context you want to carry across sessions.

Examples:

  • communication preferences
  • stable facts
  • durable instructions

Session scope

Session-scoped memory is tied to one conversation, run, or workflow instance.

Examples:

  • what the user asked in this thread
  • decisions made during the current run
  • temporary context that may not belong in the long-term profile

The two practical memory buckets

For most teams, these are the only distinctions that matter early on:

Long-term memory

Stored at the user level and retrieved across multiple interactions.

You usually inspect this with GET /v1/memory/profile/:userId.

Session memory

Stored or surfaced for one active conversation or workflow.

You usually inspect this with GET /v1/memory/session/:sessionId.

Memory types

RetainDB extracts and stores seven memory types. These map to what kind of statement a memory captures:

TypeWhat it capturesExample
factualStable facts about the user"Alex works at Stripe"
preferenceCommunication style, tool choices, tastes"User prefers concise answers"
eventThings that happened at a point in time"Deployed to production on March 15"
relationshipConnections between people or entities"Alex reports to Jordan"
opinionStated views or assessments"User thinks Tailwind is overrated"
goalObjectives being actively worked toward"User is trying to reduce database latency"
instructionExplicit directives for future behavior"Always respond in bullet points"

You do not need to assign types manually. The extraction pipeline classifies memories automatically. What matters more is whether the memory belongs in the user profile, the current session, or not at all.

Info
`instruction`-type memories carry the highest retrieval weight during context queries because they represent explicit behavioral directives. Write them intentionally.

The write-to-read loop

RetainDB memory usually follows this path:

  1. your app writes content or ingests a session
  2. RetainDB validates the request and accepts the write
  3. background extraction and indexing may continue asynchronously
  4. retrieval surfaces return pending or processed results in the matching scope

That is why include_pending shows up in several read endpoints. It bridges the gap between accepted and fully processed.

What a healthy model looks like

A healthy first implementation usually looks like this:

  • project represents one real application boundary
  • user id is stable across sessions
  • session id changes per conversation or run
  • long-term instructions go to user memory
  • temporary context stays session-scoped

What causes bad results

Overloading the session id

If every request gets a random session id, your “memory doesn’t work” bug may just be that nothing is ever being read in the same scope twice.

Treating all context as durable

Not everything belongs in long-term memory. A one-off task note should not necessarily become part of the user's lasting profile.

Using inconsistent identifiers

alex, Alex, and alex@example.com are three different identities if your app treats them that way.

What to remember

If you only keep four rules in your head, use these:

  1. project is the hard boundary
  2. user_id is long-lived identity
  3. session_id is short-lived workflow context
  4. retrieval quality starts with clean scope, not clever prompting

Next step

If you want the system-level picture, go back to architecture overview. If you want to validate the model through a real endpoint, continue to memory search.

Was this page helpful?

Your feedback helps us prioritize docs improvements weekly.