# Migrate from Mem0

> Export your memories, bring them across and keep your Mem0 calls: tested, with real output.

Move from Mem0 to LLMSlim: export memories with get_all, import them with llmslim import mem0 (or a Memory.add loop on 0.12), and keep your code with the Mem0-compatible Mem0Memory.

Category: Migration · Version: 0.12 · Updated: November 2026 · 6 min read

## Switch one import

Method names, keyword arguments and return shapes follow Mem0 2.x. Pass a SQLite path, a store or a database URL, as for `Memory`.

app.py:

```python
# from mem0 import Memory
from llmslim.memory.compat import Mem0Memory as Memory

memory = Memory("memory.db")
memory.add([{"role": "user", "content": "I moved to Pune last month."}], user_id="asha")

hits = memory.search("Where does Asha live?", filters={"user_id": "asha"})
for hit in hits["results"]:
    print(hit["score"], hit["memory"])
print(hits["context"])  # the selected turns, ready for a prompt
```

## What it does differently

The differences are deliberate, and they fail loudly rather than silently:

- **Nothing is extracted.** `add` stores turns verbatim; every returned event is `ADD`.
- **`search`** selects the turns that answer the question within a token `budget` (an LLMSlim extension, default 2,000), returns them ranked by a lexical overlap `score`, and also returns the prompt-ready text under `"context"`. `rerank=True` uses LLMSlim's optional cross-encoder (`llmslim[semantic]`); `threshold` and `explain` are ignored.
- **Filters** match `user_id`, `agent_id` and `run_id` exactly, and at least one is required. Any other filter key raises `ValueError` instead of being ignored. Scope ids go inside `filters`, as Mem0 2.x requires.
- **`expiration_date` and `reference_date`** aren't supported and raise.
- **`get_all`** returns the newest `top_k` (default 20) of a scope; **`history`** returns a turn's current state only, since there is no extraction history; **`reset`** raises, rather than deleting every user's memory.
- **`from_config`** ignores LLM, embedder and vector-store settings; a `{"store": path}` entry selects a SQLite file.

## Export your memories from Mem0

Mem0's `get_all` lists a scope's memories as `{"results": [...]}`; on the Platform it is paged, 200 at a time, with a `next` link while more remain. Write each memory as one JSON line. The Platform's memory export writes JSON shaped by a schema you define, which isn't this format.

export_mem0.py:

```python
import json

from mem0 import MemoryClient

client = MemoryClient()  # reads MEM0_API_KEY
user_ids = ["asha", "ravi"]  # the users whose memories you are moving

with open("mem0-export.jsonl", "w", encoding="utf-8") as out:
    for user_id in user_ids:
        page = 1
        while True:
            batch = client.get_all(filters={"user_id": user_id}, page=page, page_size=200)
            for memory in batch["results"]:
                memory.setdefault("user_id", user_id)
                out.write(json.dumps(memory, ensure_ascii=False) + "\n")
            if not batch.get("next"):
                break
            page += 1

# Open-source Mem0 returns every memory of a scope in one call:
#   Memory.from_config(config).get_all(filters={"user_id": user_id}, top_k=100_000)["results"]
```

mem0-export.jsonl (2 of 6 lines):

```json
{"id": "3f1c2a9e-5b7d-4e21-9a0c-1d2e3f4a5b01", "memory": "Is allergic to peanuts", "user_id": "asha", "metadata": null, "categories": ["health"], "created_at": "2026-03-02T09:14:11.482913-08:00", "updated_at": "2026-03-02T09:14:11.482931-08:00", "expiration_date": null}
{"id": "3f1c2a9e-5b7d-4e21-9a0c-1d2e3f4a5b05", "memory": "Works as a data engineer in Bengaluru", "user_id": "ravi", "agent_id": "career-coach", "metadata": null, "categories": ["professional_details"], "created_at": "2026-06-05T22:40:00.000000-07:00", "updated_at": "2026-06-05T22:40:00.000000-07:00", "expiration_date": null}
```

This script follows Mem0's SDK (mem0ai 2.2.1) but wasn't run against Mem0: we have no Mem0 account. Everything below was run on a sample export in this shape, six memories for two users, and the outputs are copied from that run.

## Bring your memories

0.12 has no importer, so add the memories in a loop. Unlike an importer, the loop stores everything again if you run it twice. 1.0 adds `llmslim import mem0`, which reads the same file and skips what is already there: see [the 1.0 preview](https://www.llmslim.app/docs/1.0/migrate-from-mem0#bring-memories).

import_mem0.py:

```python
import json

from llmslim.memory import Memory

memory = Memory("memory.db")
count = 0
with open("mem0-export.jsonl", encoding="utf-8") as export:
    for line in export:
        item = json.loads(line)
        memory.add(
            {"role": "user", "content": item["memory"]},
            user_id=item.get("user_id"),
            agent_id=item.get("agent_id"),
            run_id=item.get("run_id") or item.get("session_id"),
            timestamp=item["created_at"],
            metadata={"source_id": item["id"]},
        )
        count += 1
print(count, "memories added")
```

output:

```text
6 memories added
```

Mem0's memories are facts its model extracted ("Is allergic to peanuts"), not what was said, and they are stored as they are. From then on, what you `add` is stored word for word.

## Check it

`Mem0Memory` answers the calls your Mem0 code makes; `Memory` is LLMSlim's own API, with a token budget. This ran on 0.12.0 from PyPI and on main, with the same output. The token counts come from tiktoken (`pip install "llmslim[fast-tokens]"`); without it they are estimated at about 4 characters per token.

check.py:

```python
from llmslim.memory import Memory
from llmslim.memory.compat import Mem0Memory

# Code written for Mem0 keeps its calls: the same method names, filters and result shape.
mem0_style = Mem0Memory("memory.db")
hits = mem0_style.search("What is Asha allergic to?", filters={"user_id": "asha"})
for hit in hits["results"]:
    print(f'{hit["score"]:.3f}  {hit["memory"]}')
coach = mem0_style.get_all(filters={"user_id": "ravi", "agent_id": "career-coach"})
print(len(coach["results"]), "memories for ravi with career-coach")

# LLMSlim's own API: the turns that answer the question, within a token budget.
memory = Memory("memory.db")
for question in ["Where did Asha move to?", "Where does Asha live now?"]:
    context = memory.search(question, user_id="asha", budget=40)
    print(f"{question} ({context.tokens} of {context.history_tokens} tokens)\n  {context.text}")
```

output (the same on 0.12.0 and on main):

```text
0.642  Is allergic to peanuts
0.344  Is going to Jaipur in December for her sister's wedding
0.179  Moved to Pune in September 2026, to Koregaon Park
0.000  Prefers window seats on flights
2 memories for ravi with career-coach
Where did Asha move to? (31 of 107 tokens)
  [2026-09-21 (Mon) 15:30] user: Moved to Pune in September 2026, to Koregaon Park
Where does Asha live now? (21 of 107 tokens)
  [2026-03-02 (Mon) 17:14] user: Is allergic to peanuts
```

The last two lines show the limit of lexical relevance. Mem0's memories are short facts without their subject, so "Where did Asha move to?" shares the word "move" with "Moved to Pune" and finds it, while "Where does Asha live now?" shares no word with it, and the budget goes to the oldest memory instead. For questions worded unlike what was stored, use `relevance="semantic"` (`pip install "llmslim[semantic]"`), or a budget that holds the whole history.

## When you're ready, use Memory itself

`Mem0Memory` wraps `llmslim.memory.Memory`, which has the rest: per-call budgets and time windows, sections for standing requests, preferences and conflicts, and the stores. See the [Python quickstart](https://www.llmslim.app/docs/quickstart-python).

## How they compare

Mem0 extracts facts with an LLM when you add; LLMSlim stores turns and selects from them when you search, with no model call. [LLMSlim vs Mem0](https://www.llmslim.app/compare/mem0) has the benchmark results with their confidence intervals, where Mem0 is better, and both pricing pages. Coming from Zep instead? [LLMSlim vs Zep](https://www.llmslim.app/compare/zep) shows the closest path, through JSONL. This guide is also in the repository, as [docs/MIGRATE_FROM_MEM0.md](https://github.com/Thanatos9404/llmslim/blob/main/docs/MIGRATE_FROM_MEM0.md).

## FAQ

### Does it call an LLM when I add memories?

No. `add` stores each turn word for word and makes no model call, so `infer`, `prompt` and `memory_type` are accepted and ignored.

### Does it cover Mem0's hosted client?

No. `Mem0Memory` follows the interface of Mem0's `Memory` class, the open-source library, in its 2.x shape. Your memories from the hosted Platform still come across: export them with `MemoryClient.get_all`, as above.

### How do LLMSlim and Mem0 compare?

In round 3 (LLMSlim Core 0.9.0, read by Claude Haiku 5.5), the default LLMSlim and Mem0's open-source library were level on LoCoMo at about 2,500 tokens, 91.7% and 91.0%, at about a third of the cost per question. [LLMSlim vs Mem0](https://www.llmslim.app/compare/mem0) has every number with its confidence interval, where Mem0 is better, and both pricing pages.

## Related

- [Python quickstart](https://www.llmslim.app/docs/quickstart-python.md)
- [Storage backends](https://www.llmslim.app/docs/storage-backends.md)

Canonical page: https://www.llmslim.app/docs/migrate-from-mem0
