xmemory vs Letta
Letta descends from MemGPT, the paper that framed an LLM as an operating system paging memory in and out of a fixed context window. The product today is an agent runtime: conversations, tools, hosted computers, skills, and a memory model where the agent keeps what it knows in Markdown files inside a git repository and edits them with ordinary file tools. xmemory is not a runtime. It is a memory engine a runtime calls, so the honest frame is agent-directed file editing versus schema-directed record mutation, and a Letta agent can use both. The file-memory half of that is what the Why page argues against; this page is the comparison in full.
Documentation reviewed 23 October 2026: Letta MemFS, memory and dreaming, memory in the Agent SDK, shared memory and the MemGPT paper; on our side How xmemory works, XMD and the API.
What Letta does
Section titled “What Letta does”Each Letta agent owns a git repository, which MemFS projects onto wherever the agent runs. Every
memory is a Markdown file with name and description frontmatter; files at the root (or under
system/ for older agents) are loaded into the system prompt every turn, and directories with
their own MEMORY.md index stay out of context until the agent follows a signpost into them.
Edits become memory when committed and pushed, so there is a history, and cloud agents can share a
repository. Skills live in the same tree and travel with the agent.
Consolidation is done by dreaming: background subagents that review recent conversations and
update memory, triggered after a number of steps or on context compaction, optionally with a
second subagent reviewing proposals first. /init, /doctor and /remember give the user ways
to bootstrap, audit and teach. There is no semantic index by default; a search mod adds keyword search, with semantic and hybrid
modes when an index is configured, and conversation history is searched separately.
For a single agent working on a codebase or with one person, this is a pleasant system. The memory is readable, diffable and portable, and the agent is good at files.
Where xmemory is stronger
Section titled “Where xmemory is stronger”Structure is a contract, not a habit. In Letta the structure of memory is whatever the agent
decided to write, under the headings and files it chose; /doctor exists because that drifts. An XMD schema fixes the structure outside the agent: these objects,
these fields, these allowed values, this key. The agent still writes in plain language, but what
lands is a record the next agent, the next model version and your own code can rely on. That is
the difference between a convention and a specification, and it is the whole thesis of
Schema as the Core of Reliability.
Updates resolve by key, not by editing prose. A Letta agent updates memory immediately when it learns something, by finding the right sentence in the right file and editing it; dreaming adds consolidation on top. Whether the edit lands in the right place, and whether another file repeats the old fact, depends on the agent’s judgement each time. In xmemory “the customer moved to Pro” is extracted, matched to the customer’s record by key, applied, and kept as lineage, inside the write. The rule for where a fact lives is in the schema, not in the agent’s reading of the tree.
Reads are a typed query contract, not an agent task. MemFS leaves exhaustive filtering, joins and aggregation to the agent or application: it can follow the index, search files, or write code to scan them, and the answer is as complete as that work was. xmemory provides those operations over schema-defined records through its read interface, and can hand back the rows. “How many”, “which ones”, “since when” and “what is still missing” are the questions a file tree has no primitive for, and the ones operational memory exists for.
Context cost is a schema decision, not a filing decision. Letta keeps root files in the prompt every turn and relies on the agent’s filing discipline to keep that small. In xmemory stored records need not be included on every turn; they are retrieved on demand, and a read returns the slice of state the question needs. Toloka’s independent evaluation measured that effect against document search rather than against Letta, and found xmemory’s compact answers cut the model bill by 26%.
Access control reaches the field. Letta has organisation roles, agent and conversation visibility and tool permissions, and shared memory is a repository several cloud agents commit to, with git history recording who changed what. Those documented controls do not establish field-level permissions within memory records. xmemory scopes by field: which agents may read or write which values, with lineage on every one. Once memory is shared across agents, teams or customers, that granularity is what lets one store serve all of them.
On evidence. Letta publishes a leaderboard of model performance inside its runtime, and the MemGPT paper evaluated document analysis and multi-session chat; we have not run Letta on our benchmarks and will not quote numbers we do not have. What we can point to is adjacent: in the white paper, code-generated Markdown memory harnesses reached 12% and 40% on the Splitwise task against xmemory’s 95.2%. Those harnesses were not Letta. These results motivate testing file-based memory on stateful workloads; they do not establish Letta’s performance.
Choosing
Section titled “Choosing”Choose Letta when you want a complete agent runtime and memory that agents and people read as files: readable, diffable, shared through a repository, reviewed in a diff. Choose xmemory for the part of memory that has to behave as state: written by several agents, read by code, filtered and counted, and correct by construction rather than by review. The two fit together: xmemory exposes MCP, and a Letta agent that keeps its persona in a file can keep its facts in a schema.
Letta’s memory files as an XMD schema
Section titled “Letta’s memory files as an XMD schema”Letta’s bootstrap memory is a persona file, a file about the human, and durable project facts and workflow rules. Here is the human and project half as a schema for one project, which is what you would put beside a runtime like Letta’s rather than inside its repository.
xmd_version: v1title: Working memorydescription: What the agent knows about the person it works with and the project, as current facts.objects: Person: description: The person the agent works with. One record per person. fields: name: { type: str, required: true } role: { type: str, required: false } timezone: { type: str, required: false, description: "IANA name such as Europe/London." } primary_key: [name] Preference: description: >- One stated working preference of a person, on one topic. A new statement on the same topic replaces the previous value. fields: person_name: { type: str, required: true } topic: type: str required: true enum: [reply_length, commit_style, review_depth, tone, working_hours] description: >- The aspect the preference is about. Map wording to the closest label, so "keep answers short" and "shorter responses" both go to reply_length. Extract only preferences that fit one of these categories. Skip unrelated preferences rather than forcing a match. value: { type: str, required: true, description: "The preference as stated, in a short phrase." } primary_key: [person_name, topic] WorkflowRule: description: >- A durable rule about how work on this project is done, such as a branch policy or a release checklist step. This instance covers one project. A restated rule updates the existing record and leaves status unchanged; a statement that the rule no longer applies sets status to retired; only an explicit statement that it applies again sets it back to active. fields: name: { type: str, required: true, description: "A stable short identifier for the rule." } rule: { type: str, required: true } status: { type: str, required: true, enum: [active, retired], default: active } primary_key: [name]relations: prefers: description: Connect a Preference to the Person who holds it. objects: preference: { type: Preference, on_delete: cascade } person: { type: Person, on_delete: cascade } keys: one_person_per_preference: [preference]human.md becomes a Person plus keyed Preference records, with topic bounded so that “keep
replies short” and “shorter responses” land on the same (Alex, reply_length) record instead of
two. A project rule that gets restated updates by name; one that is dropped is set to retired,
and the old text stays in lineage; the description says what reactivates it. The persona can
remain in the prompt as a file.
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.