# xmemory vs Mem0

> Mem0 is a fixed memory pipeline that stores extracted facts as ranked text. xmemory is an engine that runs the memory schema you write, supporting Mem0-style fact capture on day one and structured, governed state as the workflow evolves.

Canonical page: https://xmemory.ai/compare/mem0/

Both products sit between the agent and the model, and both use an LLM to pull durable facts out
of what the agent sees. If you have used one, the other will feel familiar at the API. The
difference is who decides what a memory is. In Mem0 the product decides, and you tune it with
instructions. In xmemory you decide, in a schema the engine executes. Mem0-style fact capture is
one of the memory models xmemory can express.

Documentation reviewed 23 October 2026: [How Mem0 works](https://docs.mem0.ai/core-concepts/how-it-works),
[Mem0 add](https://docs.mem0.ai/core-concepts/memory-operations/add),
[Mem0 paper](https://arxiv.org/abs/2504.19413); on our side [How xmemory works](https://xmemory.ai/integration-overview/),
[XMD](https://xmemory.ai/xmd/) and the [API](https://xmemory.ai/api/).

## What Mem0 does

`add` runs an LLM over the turns you send, extracts facts such as preferences and decisions,
embeds them, and stores facts and metadata in SQL, embeddings in a vector store, and named
entities for boosting. `search` ranks memories by semantic, keyword, entity and temporal signals
and hands you strings to put in the prompt. The automatic path is additive; corrections go through
explicit `update` and `delete` calls. Custom instructions steer what gets retained. On the hosted
platform the entities form a graph memory.

It is open source, well integrated, and good at what it was built for: remembering what a person
said across sessions and surfacing the relevant bits.

## Where xmemory is stronger

**A memory is a record, not a sentence.** Under an [XMD schema](https://xmemory.ai/xmd/) every fact has a type, a
place, and optionally a key and relations. Questions about the current value of a setting, how
many incidents occurred since Monday, which accounts a release touched, or which required facts
are still missing need more than ranked retrieval. A query can evaluate all matching stored
records rather than return a ranked subset. That completeness is relative to the records stored,
not a guarantee that every relevant fact was captured from the source.
[Schema as the Core of Reliability](https://xmemory.ai/schema-as-the-core-of-reliability/) is the long form of this
argument; the [Why page](https://xmemory.ai/why/) has worked examples.

**Corrections are the normal case, not an exception.** Mem0 appends by default and leaves it to
your application to notice that "prefers window seats" supersedes "prefers aisle seats". In
xmemory a declared key makes that resolution part of the write: the new value replaces the old
one, the old one is kept as history, enum fields take only the values you declared, and a
required field the text cannot ground stays empty rather than being invented.

**The spec is yours to read, test and change.** Object and field descriptions are extraction
instructions, so you can see exactly why a fact was captured, run `extract` on tricky inputs before
trusting a change, and evolve the schema with a validated migration. Mem0's equivalent levers are
custom instructions and whatever your wrapper code does afterwards.

**Governance is built in.** Field-level access control, lineage for every stored value, and
observable write decisions. Mem0 scopes by user, agent and run, which is a filter, not a
permission model. The moment memory is shared across agents and teams, that distinction matters.

**On the operations that go wrong, the numbers are not close.** On our four-domain benchmark,
which deliberately tests updates, deletions, relation changes, aggregation and negative cases,
xmemory scores 97.1 F1; Mem0 scores 87.2 without graph memory and 86.1 with it
([paper, section 8.3](https://arxiv.org/html/2604.27906v1#S8.SS3)). Mem0's own LOCOMO result (26%
over OpenAI's memory baseline, 91% lower p95 latency than full context) measures long-chat recall,
a different task, and we would not read the two against each other. Toloka's
[independent evaluation](https://xmemory.ai/toloka-agent-memory-evaluation/) across eleven models did not include
Mem0, so take it as evidence about xmemory, not about this comparison. We have also written about
[why memory leaderboards are noisy](https://xmemory.ai/chasing-sota-in-ai-memory/); that still applies to ours.

## Replacing Mem0

If Mem0 is in production and your evaluations pass, there is no urgency. The signal to move is
when you find yourself writing dedup passes, cleanup jobs or prompt rules to keep its memories
consistent. That work is a schema. Write it as one, and the engine, the integrations and the
governance come with it.

## Mem0-style fact capture as an XMD schema

The loose end of the spectrum. The descriptions are the extraction instructions, and they ask for
the same things Mem0's pipeline is tuned to produce.

```yaml
xmd_version: v1
title: Conversational memory
description: Durable facts about a user, one record per fact.
objects:
  Memory:
    description: >-
      One durable fact about the user: a preference, decision, plan or stable
      personal detail. Skip greetings and anything only true for this turn.
      Write one Memory per distinct fact.
    fields:
      statement:
        type: str
        required: true
        description: >-
          The fact as a short, self-contained, third-person sentence, for example
          "Prefers window seats on long flights". Do not add what the text does not support.
      kind:
        type: str
        required: true
        enum: [preference, decision, plan, personal_detail, other]
      user_id: { type: str, required: true, description: The user identifier supplied with the input. }
      agent_id: { type: str, required: false }
      run_id: { type: str, required: false }
      topic: { type: str, required: false, description: "A one-word label for filtering, such as travel or work." }
    primary_key: []
  Entity:
    description: A person, place, organisation or product named in a Memory. Not the user.
    fields:
      name: { type: str, required: true }
      entity_type: { type: str, required: false, enum: [person, place, organisation, product, other] }
    primary_key: [name]
relations:
  mentions:
    description: Link a Memory to each Entity it names.
    objects:
      memory: { type: Memory, on_delete: cascade }
      entity: { type: Entity, on_delete: nullify }
    keys: {}
```

`primary_key: []` makes writes additive. `user_id`, `agent_id` and `run_id` are the scoping
filters; `topic` plays the role of categories; `Entity` and `mentions` represent named entities
and their links to memories. It captures the same shape of memory; Mem0's ranking, graph retrieval
and automatic dedup are its own, and you would add a key here if you want the last of those.

## The same engine, two steps tighter

When a workflow needs the *current* value rather than every value ever stated, model that
directly. Key on the user and a narrowly defined attribute, never on a broad topic, or unrelated
preferences will collapse into one record.

```yaml
objects:
  TravelPreference:
    description: >-
      A user's current, explicitly stated travel preference. Extract each attribute
      separately; a stated change replaces that attribute's previous value.
    fields:
      user_id: { type: str, required: true }
      attribute:
        type: str
        required: true
        enum: [seat_preference, overnight_flights]
      value: { type: str, required: true, description: "The stated preference, such as aisle, window or avoid." }
    primary_key: [user_id, attribute]
```

Feed it "u1 prefers aisle seats and avoids overnight flights", then "u1 now prefers window seats",
and the store holds two records: `seat_preference = window`, `overnight_flights = avoid`. No
cleanup job, no prompt rule, no second sentence sitting next to the first.

One practical note. Going from the loose schema to the keyed one is a
[schema migration](https://xmemory.ai/api/#limits), and migrations do not backfill history or let you tighten an
existing key; in practice you add the new object, re-extract from the source you kept, and retire
the old one. Plan for that, and keep your source data.

## 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](https://xmemory.ai/toloka-agent-memory-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](mailto:info@xmemory.ai).
