# Mem0 mem0ai 2.2.1 (open-source Python SDK): our test log

Canonical: https://theagenticweekly.com/tests/mem0 · Last verified: 2026-10-26 · Published: 2026-10-26 · Author: Agentic Weekly (operated independently from Texas, US) · Evidence: Tested by us on 2026-10-26. Local open-weight model, not the vendor's hosted models. A smoke test on a CPU-only box, not a benchmark.

> Mem0's open-source SDK 2.2.1 stored a fact from one chat message with a local 3B model and retrieved it with a semantic search (2.04 s) on the second attempt; the first two runs failed on a missing package and an API change.

## Result at a glance

Table: Mem0 test record

| Field | Value |
|---|---|
| Result | Passed |
| Version tested | mem0ai 2.2.1 (open-source Python SDK) |
| Date and time | 2026-10-26, 09:43 to 10:04 CDT (America/Chicago) |
| Task | Using the open-source mem0ai SDK entirely locally (a local Qwen2.5-3B model for memory extraction, a local embedding model, and Mem0's local Qdrant store), add one chat message: 'I'm vegetarian and allergic to peanuts. I live in Austin and my dog is called Biscuit.' for a test user, then search 'What food does this person avoid?'. Pass means the search returns a stored memory mentioning the peanut allergy or vegetarian diet. |
| Model used | Qwen2.5-3B-Instruct (Q4_K_M) through Ollama 0.40.11 for memory extraction; nomic-embed-text v1.5 (Q4_K_M, through Ollama) for embeddings |
| Hardware | Linux x86_64 virtual machine (Debian 13), 8 vCPU (Intel Xeon, 1 thread per core), 15 GiB RAM, no GPU |
| Install | 1.72 s, 135 MB (mem0ai 2.2.1) plus the ollama client |
| add() | 411.71 s (heavily loaded machine) |
| search() | 2.04 s, top score 0.643 |

## What we found

- The memory was extracted as one sentence: 'User is vegetarian and allergic to peanuts, lives in Austin, and has a dog named Biscuit' (a single combined memory rather than four separate facts).
- The search returned that memory with a similarity score of 0.643.
- It worked fully offline with local models; no key or account was used.

## What we ran, step by step

Table: Commands run, wall-clock time and exit code

| Step | Wall time | Exit code | Notes |
|---|---|---|---|
| Install with uv (cold, no cache) | 1.72 s | 0 | mem0ai 2.2.1; 135 MB. Load 13.69. |
| Task command, first run | 3.47 s | 1 | FAILED at import: the Ollama embedder needs the separate 'ollama' Python package, which mem0ai did not install. Load 17.28. |
| Install ollama client (needed for local models) | 0.65 s | 0 | Added by hand. |
| Task command, second run | 10 min 11 s | 1 | add() worked; FAILED at search(): 'Top-level entity parameters are not supported in search(). Use filters={...} instead.' Our script used the older user_id= argument. Load 17.26. The slow time is the add call under heavy machine load. |
| Task command, third run (search with filters) | 6 min 56 s | 0 | PASS: add() took 411.71 s (a local 3B model on a heavily shared CPU; load 20.12 to 20+), search() 2.04 s. |

Exact commands (paths shortened)

```
# Install with uv (cold, no cache)
uv venv -q -p 3.13 work/py/mem0 && VIRTUAL_ENV=work/py/mem0 uv pip install --no-cache -q mem0ai && du -sm work/py/mem0 | cut -f1 && VIRTUAL_ENV=work/py/mem0 uv pip list 2>/dev/null | grep -i -E '^(mem0ai|mem0ai) '

# Task command, first run
work/py/mem0/bin/python tasks3/mem0_task.py

# Install ollama client (needed for local models)
VIRTUAL_ENV=work/py/mem0 uv pip install --no-cache -q ollama

# Task command, second run
work/py/mem0/bin/python tasks3/mem0_task.py

# Task command, third run (search with filters)
work/py/mem0/bin/python tasks3/mem0_task.py
```

## Raw output (excerpts)

What Mem0 stored and returned

```
{
 "add": {
  "results": [
   {
    "id": "d727bea0-e15e-4df5-abd0-884db27f30dd",
    "memory": "User is vegetarian and allergic to peanuts, lives in Austin, and has a dog named Biscuit",
    "event": "ADD"
   }
  ]
 },
 "search_hits": [
  [
   "User is vegetarian and allergic to peanuts, lives in Austin, and has a dog named Biscuit",
   0.643
  ]
 ]
}
```

The task script (tasks3/mem0_task.py)

```
import json, time, os, shutil
os.environ["MEM0_TELEMETRY"] = "False"
shutil.rmtree("/tmp/mem0-qdrant", ignore_errors=True)
from mem0 import Memory
cfg = {
  "llm": {"provider": "ollama", "config": {"model": "qwen2.5-3b", "temperature": 0, "max_tokens": 400, "ollama_base_url": "http://127.0.0.1:11434"}},
  "embedder": {"provider": "ollama", "config": {"model": "nomic-embed-text", "ollama_base_url": "http://127.0.0.1:11434", "embedding_dims": 768}},
  "vector_store": {"provider": "qdrant", "config": {"path": "/tmp/mem0-qdrant", "embedding_model_dims": 768, "on_disk": True}},
  "history_db_path": "/tmp/mem0-history.db",
}
t = time.perf_counter(); m = Memory.from_config(cfg); init_s = round(time.perf_counter() - t, 2)
res = {"init_s": init_s}
t = time.perf_counter()
r = m.add([{"role": "user", "content": "I'm vegetarian and allergic to peanuts. I live in Austin and my dog is called Biscuit."}], user_id="alex")
res["add_s"] = round(time.perf_counter() - t, 2); res["add_result"] = r
t = time.perf_counter()
s = m.search("What food does this person avoid?", filters={"user_id": "alex"}, limit=3)
res["search_s"] = round(time.perf_counter() - t, 2)
items = s["results"] if isinstance(s, dict) else s
res["hits"] = [(x.get("memory"), round(x.get("score", 0), 3)) for x in items]
txt = " ".join(h[0].lower() for h in res["hits"])
res["ok"] = ("peanut" in txt) or ("vegetarian" in txt)
print("RESULT_JSON " + json.dumps(res))
```

## Gotchas and things that broke

- The Ollama embedder import failed until we installed the separate 'ollama' package.
- search() rejects user_id=; filters={'user_id': ...} is required in 2.2.1, so older tutorials fail with a ValueError.
- On start it logged that spaCy and fastembed are not installed and that keyword (BM25) search is disabled; those are optional extras we did not install.

## What we did not test

- Mem0's hosted platform, pricing tiers and quotas: only the open-source SDK was run.
- Graph memory, multi-user isolation, updates and deletes, and the optional extras (spaCy, fastembed).
- Retrieval quality over more than one fact: a single message and a single query is a smoke test, not a benchmark.
- Timing: add() ran while another model job loaded the machine.

## Reproduce it

Versions change. These commands install whatever is latest on the day you run them unless a version is pinned, so expect different results later. The version we measured is in the table above.

```
uv venv -p 3.13 .venv && VIRTUAL_ENV=.venv uv pip install mem0ai ollama
# serve a local chat model and nomic-embed-text with Ollama, then run the script above
```

## How to read this test

Every number on this page was measured on this one machine, which also ran other jobs, so timings are indicative and vary run to run. A pass means our small task worked once or as stated, a fail means it did not work as we ran it; neither says how the tool behaves with a vendor's frontier model, on a GPU, or at scale. Where a tool could not run without an account or a GPU, we say so instead of guessing.

See the [testing rig](https://theagenticweekly.com/methodology#testing-rig) for the hardware, the local model and the rules we follow, and the [test hub](https://theagenticweekly.com/tests) for every other test.

## FAQ

### Does Mem0 work without an API key?

The open-source SDK did in our run: with a local Ollama model, a local embedding model and its local Qdrant store, it stored and retrieved a memory with no account or key.

## Sources

- [Mem0 repository](https://github.com/mem0ai/mem0) (fetched 2026-10-26)

## Related

- [All test logs](https://theagenticweekly.com/tests)
- [Methodology and testing rig](https://theagenticweekly.com/methodology#testing-rig)
- [Mem0 facts and sources](https://theagenticweekly.com/tools/mem0)

## How to cite

Agentic Weekly, "Mem0 mem0ai 2.2.1 (open-source Python SDK): our test log", last updated 2026-10-26, https://theagenticweekly.com/tests/mem0
