xmemory vs Supermemory
Supermemory is the broadest product on these pages. It takes documents, PDFs, audio, URLs and connector feeds, chunks and indexes them for retrieval, and in a second pass extracts memories into a graph that knows which fact is latest. It ships profiles, a managed RAG, a memory tool for Claude, and an open-source benchmark harness. If the question is “one API for all my context”, Supermemory is a fair answer. The question this page is about is narrower: when an agent’s memory has to behave as state, what does each system let you specify, and what does it decide for you?
Documentation reviewed 23 October 2026: Supermemory how it works, graph memory, customization, user profiles, MemoryBench; on our side How xmemory works, XMD and the API.
What Supermemory does
Section titled “What Supermemory does”Ingestion runs a fixed pipeline: extract text (OCR, transcription, page fetch), contextual
chunking, embedding, indexing. Chunks are searchable as soon as a document is done; memories come
from a second phase the docs call dreaming, which batches related documents and extracts facts
into “a fact-based temporal graph that has vector, FTS, and graph built in”. Facts relate to each
other as updates (the newer fact wins and carries isLatest, history kept for audit), extends
(both stay valid) and derives (a fact inferred across several memories that was never stated).
Forgetting is automatic: temporary facts expire, contradictions resolve to the newest, chatter is
filtered, and memory types decay differently, with preferences strengthening on repetition.
A profile is an automatically maintained set of facts per namespace: a static collection of
long-lived facts, a dynamic collection of recent context, and topic buckets (a default
preferences bucket plus any you define by name and description) into which a classifier sorts
extracted facts. Each entry is a natural-language sentence with an id. Namespaces are hard
tenancy boundaries with scoped API keys; metadata gives soft filters inside one. Extraction is
steered by two free-text fields, an organisation-wide organizationalContext and a per-namespace
supportingContext, and existing memories are not reprocessed when they change.
Where xmemory is stronger
Section titled “Where xmemory is stronger”Specified, not steered. Supermemory’s control over extraction is prose: context strings that
guide the extractor, and bucket descriptions that steer a classifier afterwards, with the docs
saying nothing about how strictly either is followed. An
XMD schema is executable. Field descriptions are the extraction instructions, enums
bound the values, keys decide identity, relation keys fix cardinality, and extract lets you test
a change against awkward inputs before you trust it. When the extractor meets “the plan is now
Pro”, it is not interpreting a hint about what matters; it is filling plan on the customer’s
record from an allowed set. The long version is
Schema as the Core of Reliability.
Supersession by key, not by judgement. Supermemory’s updates relation is the closest thing
to xmemory’s write path among these products: the newest fact wins and the old one stays for
audit. The difference is who decides that two facts are about the same thing. In Supermemory the
engine infers relatedness; in xmemory the schema states it, as a primary key, and a mention that
carries the key hits the record every time. The same goes for derives: Supermemory will infer
facts across memories on its own initiative and lets you approve, decline or undo low-confidence
ones afterwards; xmemory’s grounded inference is bounded by what the descriptions license. Those
controls review generated inferences; schema descriptions specify the intended extraction
beforehand. The
Why page has the worked “who is Kevin’s manager” case.
State, not a profile. A Supermemory profile is a set of natural-language facts, sorted into
static, dynamic and topic buckets, that you put in the prompt. It is useful, and each entry is a
sentence rather than a typed record. xmemory keeps the facts as typed records over SQL, so
“which customers are on Pro and overdue”, “how many open commitments does this person have”,
and “which required fields are still empty” are queries over all matching stored records rather
than a selection of facts, and the rows can go to code instead of a model. Lifecycle is explicit
in the same way: a fact that should stop being current gets a status or a date the schema
declares, instead of a decay rule the engine applies to a memory type.
Breadth is theirs; depth is ours. Supermemory ingests files, audio and connector feeds and runs a managed RAG beside the memory; xmemory takes text and structured input and does one thing with it. If you need a single managed stack for documents and recollection, Supermemory covers more surface. If the memory is the thing a workflow acts on, the narrower contract is the point. (Audio, files and connectors still reach xmemory, through whatever already turns them into text.)
Tenancy, then fields. Namespaces with scoped keys are a clean hard boundary, and metadata is a workable soft filter. Those controls do not establish field-level permissions within a memory record. xmemory scopes reads and writes by field, with lineage on every stored value, so one instance can serve several agents and teams with different views of the same records.
The measurements. Supermemory’s own MemoryBench runs LoCoMo, LongMemEval and ConvoMem across providers, which is a good contribution and measures recall over conversations. On our four-domain end-to-end benchmark (updates, deletions, relation changes, aggregation, negative queries) Supermemory scored 80.49 F1 against xmemory’s 97.10. On the Splitwise task, where every read needs arithmetic, it scored 73.75%, the best of the third-party systems we ran, against 95.2% (white paper; numbers also in Chasing AI memory SOTA). The paper’s setup: the managed service, hybrid mode, a 0.7 decision threshold tuned toward precision, every write awaited to completion including asynchronous processing. These results measure the tested configuration. They show a substantial gap on these workloads, but do not isolate its cause or establish the best result achievable with tuned context strings.
Choosing
Section titled “Choosing”Choose Supermemory when you want one managed service for ingesting everything, a RAG over the documents and a profile over the person, and the main consumer is a model reading context. Choose xmemory when the memory is written by agents, read by code, corrected often and counted on, and you would rather state the rules than tune the hints. The facts Supermemory extracts for you are a reasonable first draft of what your schema should declare.
Supermemory’s memory types as an XMD schema
Section titled “Supermemory’s memory types as an XMD schema”Supermemory sorts memories into facts, preferences and episodes and applies a different decay rule to each. The schema below models a slice of that, a person’s preferences and commitments, with identity and lifecycle as fields you can query rather than behaviour you infer from a type.
xmd_version: v1title: Personal contextdescription: What is known about a person, their stated preferences, and the commitments they have mentioned, as current state.objects: Person: description: The person whose context this is. One record per person. fields: user_id: { type: str, required: true, description: "The identifier supplied with the input; do not invent one." } name: { type: str, required: false } primary_key: [user_id] Preference: description: >- One stated preference on one specific dimension. A new statement on the same dimension replaces the value; statements on other dimensions are separate records. Extract only preferences that fit a listed dimension; skip the rest. fields: user_id: { type: str, required: true } dimension: type: str required: true enum: [seat_position, overnight_flights, meeting_start_time, reply_length, diet] description: >- The specific thing the preference is about. "Window seats" is seat_position; "no red-eyes" is overnight_flights; "nothing before 10" is meeting_start_time. category: type: str required: false enum: [travel, schedule, communication, food] description: The broad topic the dimension belongs to, for filtering. value: { type: str, required: true } primary_key: [user_id, dimension] Commitment: description: >- One occurrence of something the person said they will do or must attend. Each distinct occurrence is its own record: a second chemistry exam is a new Commitment, not an update to the first. A later mention of the same occurrence (same thing, same or rescheduled date, referred to as "the exam" or "it") updates that record: a new date changes due_on, "done" or "cancelled" changes status. Nothing expires on its own. fields: user_id: { type: str, required: true } occurrence_id: type: str required: true description: >- A stable handle for this occurrence: the thing plus the first date mentioned, e.g. chemistry-exam-2026-11-04. Reuse it when later text refers to the same occurrence, even if the date moves. This example covers dated commitments with at most one occurrence of a thing per date; an undated commitment ("I need to book a dentist appointment") or two occurrences on one day need a different identity rule, such as a sequence suffix. what: { type: str, required: true, description: "Short noun phrase, e.g. \"chemistry exam\"." } due_on: { type: str, required: false, description: "YYYY-MM-DD, current scheduled date." } status: { type: str, required: true, enum: [pending, done, cancelled], default: pending } primary_key: [user_id, occurrence_id]relations: prefers: description: Connect a Preference to its Person. objects: preference: { type: Preference, on_delete: cascade } person: { type: Person, on_delete: cascade } keys: one_person: [preference] committed_to: description: Connect a Commitment to its Person. objects: commitment: { type: Commitment, on_delete: cascade } person: { type: Person, on_delete: cascade } keys: one_person: [commitment]“I prefer window seats” and “I avoid overnight flights” land on two records, because the key is
the specific dimension, not the travel category. “Exam tomorrow drops after it expires” becomes a
Commitment with a due_on you filter on and a status that changes when the person says so;
nothing decays silently, and “what is still pending this week” is a query. The identity rule is
deliberately scoped to dated, one-per-day commitments; widen it before relying on it for the
undated or repeated kind. Supermemory’s
“preferences strengthen with repetition” has no direct equivalent here: a schema could carry a
count, but that is an explicit alternative you would design and test, not a reproduction of the
behaviour. More generally, the needs behind updates, extends and derives are met by
different means: a key identifies the record an update lands on, enrichment is a field, a record
or a relation depending on what is being added, and inference is whatever a description
explicitly allows.
Why we think this matters, and for whom
xmemory works well for short-running agents, and it is at its best for repeated tasks, where each run adds to a body of knowledge the next run can use. Long-horizon agents deserve a special mention, because there is very little objective evidence yet about what memory design works for them. Our working belief, and the reason xmemory exists: an agent running a long, multi-step task does better on structured state than on accumulated context. A schema gives it an explicit feedback loop at write time (what was accepted, what was rejected, what changed), so memory is updated rather than bloated and the trajectory stays on course: fewer re-reads, faster steps, more reliable outcomes.
If that is your workload, try xmemory on it. We are building objective measurements for this claim. The Toloka evaluation is our first independent measurement of the benefits of structured memory; evaluating changing working state over long-horizon tasks is next, and we would welcome collaborators on it. Write to info@xmemory.ai.