AI Coding AgentsSelf-HostingAI
Mem0 self-hosted with Docker and Ollama: long-term AI memory, OpenMemory replaced (Linux, Windows, Mac)
Before you start
- 21 min read
Boxes marked Run in terminal are what you type; plain text explains why. Check what you need first

What you get in one minute#
Mem0 is an open-source (Apache-2.0) memory layer that lets AI apps remember facts about you between chats; the old OpenMemory MCP server was sunset and removed from the repository in July 2026, so this guide shows the replacement: Mem0 on your own machine with Ollama and Qdrant.
Logo: the official Mem0 project (github.com/mem0ai/mem0)
Mem0 reads a conversation, keeps the useful facts ("vegetarian", "prefers dark mode"), and finds them again when a later question needs them. Use it to give your own scripts and agents a memory. Older OpenMemory tutorials describe a project that no longer exists in the main repository.
| What | Value (official docs and releases, read October 2026) |
|---|---|
| Current version | Mem0 Python SDK v2.2.1, released 25 September 2026 (GitHub release and PyPI) |
| Licence | Apache-2.0 (repository LICENSE) |
| OpenMemory | Sunset. Removed from the Mem0 repository by pull request #6530 (merged July 2026); a read-only copy sits in mem0ai/openmemory |
| Time needed | About 30 minutes for the local route, 20 more for the server (our estimate, not measured) |
| Size and RAM | The project publishes no figures. Ollama lists 4.9 GB for llama3.1:8b and 274 MB for nomic-embed-text |
| Ports | Ollama 11434, Qdrant 6333; server API 8888, dashboard 3000, Postgres 8432 |
| Official docs | docs.mem0.ai and the repository |
At a glance:
- What it is: a Python and Node library plus an optional Docker server that stores memories and searches them by meaning.
- OpenMemory: retired; its own notice points to the self-hosted Mem0 server.
- Default calls go to the cloud: both the library and the server use OpenAI (
gpt-5-miniandtext-embedding-3-small) until you change them. - Ollama works in the library: every byte can stay on your machine. The server image only bundles OpenAI, Anthropic and Gemini.
- MCP is cloud-only: the official MCP server is hosted by Mem0 and needs an account; the self-hosted server has REST only.
Pick a route:
| Route | Where memories live | LLM and embedder | MCP for AI tools | Best for |
|---|---|---|---|---|
| A. Library + Ollama + Qdrant (Steps 1 to 4) | Your machine | Ollama, your choice | None official; you call it from code | Fully local, scripts, learning |
| B. Self-hosted server (Step 5) | Your Postgres | OpenAI by default; Anthropic, Gemini bundled | None (REST and a dashboard) | Teams, API keys, audit log |
| C. Mem0 Platform + hosted MCP (Step 6) | Mem0's cloud account | Managed by Mem0 | Yes, mcp.mem0.ai | Quickest memory in Claude Code or Cursor |
How it fits together#
Your app sends chat text to Mem0, which asks Ollama for the facts, turns each fact into numbers, and stores them in Qdrant; a search runs the same path in reverse.
Drawn for this guide from the official docs. Solid boxes are route A; dashed boxes are optional.
Before you start#
You need Ollama for the models, Docker for Qdrant, and Python 3.10 or newer. The project publishes no RAM figure.
| System | What to use |
|---|---|
| Linux | x86_64 or arm64, Docker Engine with Compose, Python 3.10+, git |
| Windows | Windows 10 or 11, Docker Desktop, Python 3.10+, git |
| Mac | macOS with Docker Desktop, Python 3.10+, git |
Install Ollama with our Ollama guide. Check each tool:
docker --version && docker compose version && python3 --version && git --version && ollama --version
On Windows run the same checks in PowerShell, with python --version instead of python3.
Checklist:
- [ ] Ollama installed and running (
ollama listanswers) - [ ] Ports 6333 and 11434 free; for Step 5 also 3000, 8888 and 8432
- [ ] Docker running, with room for the downloads
- [ ] A backup place for
~/docker_volumes/mem0 - [ ] For HTTPS only: a domain, a DNS record, ports 80 and 443
Tested by DIY Lab Hub: not yet. The commands come from the official docs and source files read in October 2026. We only ran docker compose config on the two Compose override files (Windows, Compose v5.6.1); nothing was started.
Step 1: Pull the two Ollama models#
Mem0 needs a chat model to pick out facts and an embedding model to turn them into numbers. The docs list llama3.1:8b for the chat model, and nomic-embed-text is the embedder default.
Linux#
ollama pull llama3.1:8b ollama pull nomic-embed-text ollama list
Windows (PowerShell)#
ollama pull llama3.1:8b ollama pull nomic-embed-text ollama list
Mac (Terminal)#
Same commands as Linux:
ollama pull llama3.1:8b ollama pull nomic-embed-text ollama list
Check it worked. ollama list shows both names, and curl http://localhost:11434/api/version answers (Windows: curl.exe).
Tip: Ollama listens on
127.0.0.1only. That is right for route A, because Mem0 runs on the same machine. Do not changeOLLAMA_HOSTjust to make this guide work.
Step 2: Start Qdrant in Docker#
The library defaults to a Qdrant folder under /tmp/qdrant, which a reboot may clear, so we run a Qdrant server with real storage. Our Qdrant guide explains it in depth.
Linux#
mkdir -p ~/docker_volumes/mem0/qdrant/data ~/docker_volumes/mem0/backups
cd ~/docker_volumes/mem0/qdrant
cat > docker-compose.yml << 'EOF'
name: mem0-qdrant
services:
qdrant:
image: qdrant/qdrant:v1.20.0
container_name: qdrant-mem0
restart: unless-stopped
volumes:
- ./data:/qdrant/storage
ports:
- "127.0.0.1:6333:6333"
EOF
docker compose up -d
docker compose ps
Windows (PowerShell)#
Qdrant warns against bind-mounting a Windows folder through WSL-backed Docker, so the data lives in a named volume:
New-Item -ItemType Directory -Force "$HOME\docker_volumes\mem0\qdrant" | Out-Null
New-Item -ItemType Directory -Force "$HOME\docker_volumes\mem0\backups" | Out-Null
Set-Location "$HOME\docker_volumes\mem0\qdrant"
@'
name: mem0-qdrant
services:
qdrant:
image: qdrant/qdrant:v1.20.0
container_name: qdrant-mem0
restart: unless-stopped
volumes:
- qdrant_storage:/qdrant/storage
ports:
- "127.0.0.1:6333:6333"
volumes:
qdrant_storage:
'@ | Set-Content -Encoding ascii docker-compose.yml
docker compose up -d
docker compose ps
Mac (Terminal)#
Same commands as Linux.
Check it worked. docker compose ps shows qdrant-mem0 running, and curl http://localhost:6333 returns a small JSON with the title and version (Windows: curl.exe).
Tip: The port is bound to
127.0.0.1, so only this machine can reach Qdrant. If you ever publish it wider, set an API key as in our Qdrant guide.
Step 3: Install Mem0 in a virtual environment#
Install mem0ai and the separate ollama package; the Ollama client is only in Mem0's optional llms extra.
Linux#
mkdir -p ~/mem0-local && cd ~/mem0-local python3 -m venv .venv source .venv/bin/activate pip install mem0ai ollama export MEM0_TELEMETRY=false pip show mem0ai
Windows (PowerShell)#
New-Item -ItemType Directory -Force "$HOME\mem0-local" | Out-Null Set-Location "$HOME\mem0-local" python -m venv .venv .\.venv\Scripts\Activate.ps1 pip install mem0ai ollama $env:MEM0_TELEMETRY = "false" pip show mem0ai
If PowerShell refuses the activation script, run Set-ExecutionPolicy -Scope Process Bypass for this window (general PowerShell advice, not from the Mem0 docs).
Mac (Terminal)#
Same commands as Linux.
Check it worked. pip show mem0ai prints Version: 2.2.1 (or a newer one if Mem0 has released since). MEM0_TELEMETRY=false switches off the anonymous usage events the library sends by default; set it in each new terminal before you run Python.
Tip: Skip the
mem0ai[nlp]extra for now. It needs Python 3.10 to 3.12 (the docs say spaCy has no 3.13 wheels) and an extra model download. Without it, Mem0 falls back to meaning-only search.
Step 4: Add and search your first memory with Ollama#
This script wires Mem0 to Ollama and Qdrant. embedding_model_dims must match the embedder (768 here); Qdrant's default is 1536.
Linux#
cd ~/mem0-local && source .venv/bin/activate
cat > mem0_local.py << 'EOF'
import os
from mem0 import Memory
OLLAMA = "http://localhost:11434"
config = {
"llm": {
"provider": "ollama",
"config": {"model": "llama3.1:8b", "temperature": 0.1, "max_tokens": 2000, "ollama_base_url": OLLAMA},
},
"embedder": {
"provider": "ollama",
"config": {"model": "nomic-embed-text", "embedding_dims": 768, "ollama_base_url": OLLAMA},
},
"vector_store": {
"provider": "qdrant",
"config": {"collection_name": "mem0_nomic_768", "host": "localhost", "port": 6333, "embedding_model_dims": 768},
},
"history_db_path": os.path.expanduser("~/mem0-local/history.db"),
}
m = Memory.from_config(config)
messages = [
{"role": "user", "content": "I'm vegetarian and I like dark mode in every editor."},
{"role": "assistant", "content": "Noted: vegetarian, dark mode."},
]
m.add(messages, user_id="alex")
found = m.search("What does Alex eat?", filters={"user_id": "alex"}, top_k=3)
for item in found["results"]:
print(item["memory"], item.get("score"))
EOF
python mem0_local.py
Windows (PowerShell)#
Save the Python code from the Linux block (from import os to the last print) as mem0_local.py in $HOME\mem0-local, for example with notepad mem0_local.py. Then run it:
Set-Location "$HOME\mem0-local" .\.venv\Scripts\Activate.ps1 python mem0_local.py
Mac (Terminal)#
Same commands as Linux.
Check it worked. The script prints one or more memory lines such as "Is vegetarian". The docs show results as a list with id, memory, user_id, categories, created_at and score; your wording and score will differ. The collection exists in Qdrant:
curl http://localhost:6333/collections
Tip: Restart Qdrant (
docker compose restartin its folder), run the script again, and check that the earlier fact is still in the output. That proves the storage survives.
Step 5: Run the self-hosted Mem0 server (optional)#
Use the server when several apps or people need one memory store with API keys and a dashboard: an API, a dashboard and Postgres with pgvector. The official Compose file is labelled "development" (it builds from source and runs with auto-reload), and there is no pinned production image.
Default calls leave your machine. The server sends memory text to OpenAI unless you change that, so .env needs an OpenAI key (or an Anthropic or Gemini key).
Linux#
mkdir -p ~/docker_volumes/mem0 && cd ~/docker_volumes/mem0 git clone --depth 1 --branch v2.2.1 https://github.com/mem0ai/mem0.git mem0-src cd mem0-src/server cp .env.example .env && chmod 600 .env openssl rand -base64 48 # a value for JWT_SECRET openssl rand -hex 24 # a value for POSTGRES_PASSWORD nano .env
In .env set these four lines (keep the rest):
OPENAI_API_KEY=<YOUR_OPENAI_KEY> POSTGRES_PASSWORD=<LONG_RANDOM_PASSWORD> JWT_SECRET=<LONG_RANDOM_SECRET> MEM0_TELEMETRY=false
The official Compose file publishes the API, dashboard and Postgres on every interface. An override file next to it, which Compose reads on its own, binds them to your machine (!override replaces the port list):
cat > docker-compose.override.yaml << 'EOF'
services:
mem0:
ports: !override
- "127.0.0.1:8888:8000"
mem0-dashboard:
ports: !override
- "127.0.0.1:3000:3000"
postgres:
ports: !override
- "127.0.0.1:8432:5432"
EOF
make bootstrap
make bootstrap is the official one-command start. It creates an admin and prints the login and the first API key once; copy both into a password manager.
Windows (PowerShell)#
make and lsof are not on Windows, so start the stack with Compose and use the browser wizard:
New-Item -ItemType Directory -Force "$HOME\docker_volumes\mem0" | Out-Null Set-Location "$HOME\docker_volumes\mem0" git clone --depth 1 --branch v2.2.1 https://github.com/mem0ai/mem0.git mem0-src Set-Location mem0-src\server Copy-Item .env.example .env python -c "import secrets; print(secrets.token_urlsafe(48))" python -c "import secrets; print(secrets.token_hex(24))" notepad .env
Set the same four .env lines as above. Then create the override file and start the stack:
@'
services:
mem0:
ports: !override
- "127.0.0.1:8888:8000"
mem0-dashboard:
ports: !override
- "127.0.0.1:3000:3000"
postgres:
ports: !override
- "127.0.0.1:8432:5432"
'@ | Set-Content -Encoding ascii docker-compose.override.yaml
docker compose up -d --build
docker compose ps
Open http://localhost:3000. With no admin yet it opens the setup wizard: create the admin, copy the first API key (m0sk_..., shown once), and run the test.
Mac (Terminal)#
Same commands as Linux (make needs the Xcode command line tools).
Check it worked. The official make health target uses these two checks; both should print 200:
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8888/docs
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/api/health
On Windows use curl.exe. Then store and search a memory with your key. The server has no /v1/ prefix:
curl -X POST http://localhost:8888/memories -H "Content-Type: application/json" \
-H "X-API-Key: <YOUR_MEM0_KEY>" \
-d '{"messages":[{"role":"user","content":"I love fresh vegetable pizza."}],"user_id":"alice"}'
curl -X POST http://localhost:8888/search -H "Content-Type: application/json" \
-H "X-API-Key: <YOUR_MEM0_KEY>" -d '{"query":"vegetable","user_id":"alice"}'
The first call returns the new memory IDs and an ADD event (docs). PowerShell version:
$body = @{ messages = @(@{ role = "user"; content = "I love fresh vegetable pizza." }); user_id = "alice" } | ConvertTo-Json -Depth 5
Invoke-RestMethod -Method Post -Uri http://localhost:8888/memories -Headers @{ "X-API-Key" = "<YOUR_MEM0_KEY>" } -ContentType "application/json" -Body $body
Tip: The dashboard's Memories page lists what was stored. Check it after your first real conversations; stores fill with noise fast.
Switching the server to Ollama (advanced, not tested)#
The server image bundles LLM providers openai, anthropic, gemini and embedder providers openai, gemini. Choosing another one on the Configuration page or POST /configure returns a 400 saying the provider is "not bundled in this image". The docs' recipe: add the package to server/requirements.txt (ollama>=0.3.0), add "ollama" to BUNDLED_LLM_PROVIDERS and BUNDLED_EMBEDDER_PROVIDERS in server/main.py, and rebuild with docker compose up -d --build.
The docs do not cover three things: how the container reaches Ollama (Docker Desktop offers the name host.docker.internal; Linux Engine needs another address, and Ollama must then listen beyond 127.0.0.1), the 1536-dimension vector table a 768-dimension embedder needs changed, and keeping your edit through upgrades. If local models are your goal, route A is the supported path.
Step 6: Connect your AI tools (the MCP question)#
OpenMemory used to give Claude Code and Cursor a local MCP memory. That is gone. Today:
- Hosted MCP (route C): Mem0 runs
https://mcp.mem0.ai/mcp. It needs a Platform account, and "memories you store this way live in your Mem0 account, not on your computer". - Self-hosted server: REST and a dashboard only. A community request for a server MCP is still open (issue #6370).
- Mem0's Claude Code plugin also needs a Platform key.
If you accept the cloud trade-off, the docs' command for Claude Code is:
Linux#
npx mcp-add --name mem0-mcp --type http --url "https://mcp.mem0.ai/mcp" --clients "claude code"
Windows (PowerShell)#
Same command; it needs Node.js 18 or newer:
npx mcp-add --name mem0-mcp --type http --url "https://mcp.mem0.ai/mcp" --clients "claude code"
Mac (Terminal)#
Same command as Linux.
Restart the client. On first use it opens a browser to sign in; without that, the server answers 401 Authentication required. Claude Desktop rejects mcp-add: add the URL under Settings, Connectors instead.
Check it worked. claude mcp list should show mem0-mcp (Claude Code's command, not from the Mem0 docs). Ask it to remember a fact, then start a new chat and ask for it.
Tip: If "nothing leaves my PC" is the goal, stop at route A and call Mem0 from your own code. For how MCP tools attach to a local-model chat, see our Open WebUI MCP guide.
Put it behind HTTPS (with or without Traefik)#
Only the server (Step 5) needs this, on a machine with a domain; local-only users skip it. Your browser calls the address in NEXT_PUBLIC_API_URL directly, so you need two names: one for the dashboard and one for the API. Mem0 documents no HTTPS recipe; this follows from its compose and dashboard files, and we did not run it.
Create the shared network once: docker network create proxy.
With Traefik#
On a server that already runs Traefik v3 with the Docker provider, replace the override file in ~/docker_volumes/mem0/mem0-src/server/. It removes the host ports, joins the proxy network, adds labels, and points the dashboard at the API's public name; DASHBOARD_URL is the origin the API accepts:
services:
mem0:
ports: !reset []
networks:
mem0_network: {}
proxy: {}
environment:
- DASHBOARD_URL=https://mem0.<your-domain>
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.mem0-api.rule=Host(`mem0-api.<your-domain>`)"
- "traefik.http.routers.mem0-api.entrypoints=https"
- "traefik.http.routers.mem0-api.tls=true"
- "traefik.http.services.mem0-api.loadbalancer.server.port=8000"
mem0-dashboard:
ports: !reset []
networks:
mem0_network: {}
proxy: {}
environment:
- NEXT_PUBLIC_API_URL=https://mem0-api.<your-domain>
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.mem0.rule=Host(`mem0.<your-domain>`)"
- "traefik.http.routers.mem0.entrypoints=https"
- "traefik.http.routers.mem0.tls=true"
- "traefik.http.services.mem0.loadbalancer.server.port=3000"
postgres:
ports: !reset []
networks:
proxy:
external: true
Run docker compose up -d --force-recreate there. Use your own entrypoint name if it is not https.
Check it worked. curl -I https://mem0-api.<your-domain>/docs returns an HTTP status line over HTTPS and the dashboard opens at https://mem0.<your-domain>.
Without Traefik: Caddy#
Caddy gets and renews certificates by itself. Use the same override file as above but delete both labels: blocks. Then add Caddy in ~/docker_volumes/caddy/docker-compose.yml:
services:
caddy:
image: caddy:2.11.7
container_name: caddy
restart: unless-stopped
ports:
- "80:80/tcp"
- "443:443/tcp"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./data:/data
- ./config:/config
networks:
- proxy
networks:
proxy:
external: true
The Caddyfile for a public domain (Let's Encrypt needs ports 80 and 443):
mem0.example.com {
reverse_proxy mem0-dashboard:3000
}
mem0-api.example.com {
reverse_proxy mem0:8000
}
At home, with no public domain, add tls internal inside each site block (for example mem0.home.arpa) for Caddy's own local certificate. Each device must trust Caddy's root: find it with docker exec caddy find /data -name root.crt, copy it out with docker cp, and import it (Windows: Trusted Root Certification Authorities; Mac: Keychain Access, Always Trust; Linux: your CA store; these OS steps are not from the Caddy docs). Start both stacks with docker compose up -d, then check curl -I https://mem0-api.example.com/docs.
Security and testing#
Treat the memory store like a diary, and do not put passwords or keys into text Mem0 reads. The full m0sk_ key is shown once; the server keeps only a hash.
| Control | How |
|---|---|
| Secrets | .env holds your provider key, JWT_SECRET and the database password: chmod 600 .env, never commit it |
| Ports | Keep the override file: 8888, 3000 and 8432 on 127.0.0.1 only |
| Auth | On by default. Never set AUTH_DISABLED=true outside local tests. Prefer per-user m0sk_ keys over ADMIN_API_KEY |
| Telemetry | Library and server send anonymous PostHog events unless MEM0_TELEMETRY=false |
| Ollama | Leave it on 127.0.0.1; opening OLLAMA_HOST exposes your models |
Quick tests: docker compose ps in each folder, docker compose logs --tail=100 mem0, curl http://localhost:8888/docs, ollama ps.
What Mem0 calls by default, and how to switch#
| Part | Library default | Server default | This guide (route A) |
|---|---|---|---|
| Chat model (fact extraction) | OpenAI gpt-5-mini | OpenAI gpt-5-mini | Ollama llama3.1:8b |
| Embedder | OpenAI text-embedding-3-small (1536 numbers) | Same | Ollama nomic-embed-text (768) |
| Vector store | Qdrant on disk at /tmp/qdrant | pgvector in Postgres 17 | Qdrant server on port 6333 |
| History | SQLite ~/.mem0/history.db | SQLite in /app/history | ~/mem0-local/history.db |
| Telemetry | On | On | Off |
To switch in the library, change provider and config in Memory.from_config (the docs list ollama, anthropic, gemini, groq and more). In the server, MEM0_DEFAULT_LLM_MODEL and MEM0_DEFAULT_EMBEDDER_MODEL only choose models of bundled providers. Mem0 v3 also changed the API: entity IDs go inside filters on search() and get_all(), top_k defaults to 20, threshold to 0.1, and graph memory is Platform-only.
Common mistakes#
These come from the official docs' own warnings, the pull request that removed OpenMemory, and GitHub issues.
| Mistake | Why it happens | Do this instead |
|---|---|---|
Following an OpenMemory tutorial (run.sh, port 8765, npx @openmemory/install) | The project was sunset (PR #6530); the old run.sh link now returns 404, and mem0ai/openmemory hosts an unrelated session-sync tool | Use route A or B. Treat old OpenMemory pages as history |
Installing only mem0ai and choosing Ollama | The ollama client is in an optional extra. v2.2.1 raises "The 'ollama' library is required. Please install it using 'pip install ollama'."; older builds asked "[y/N]" and died with EOF when reading a line (issues #6118, #7575) | pip install mem0ai ollama in the active environment |
| Leaving the vector size at 1536 | Qdrant's default is separate from the embedder. Issue #7736 shows Vector dimension error: expected dim: 1536, got 1024 | Set embedding_model_dims to the embedder's size and use a new collection_name |
| Keeping Qdrant's default path | The library default is on-disk /tmp/qdrant, which temp-folder cleaning can remove | Run Qdrant as in Step 2, or set path to a folder you back up |
Pulling mem0/mem0-api-server from Docker Hub | The REST page lists it, but Docker Hub shows only latest, pushed September 2025, before the auth and dashboard server | Clone the repository at v2.2.1 and use its Compose file |
| Picking Ollama on the server's Configuration page | Only OpenAI, Anthropic and Gemini are bundled; issue #7398 (open) asks for Ollama | Use route A, or rebuild the image as described above |
Editing .env, then docker compose restart | restart does not re-read env_file (the docs warn about it) | docker compose up -d --force-recreate mem0 |
| Leaving the Compose ports as shipped | The official file publishes 8888, 3000 and Postgres 8432 on every interface | Use the override file with 127.0.0.1 |
Installing mem0ai[nlp] without the spaCy model | Issue #7277 (open): the first add() tries to download it and can crash every call | Run python -m spacy download en_core_web_sm first, on Python 3.10 to 3.12, or skip the extra |
| Trusting whatever gets stored | Issue #4573 (closed) audited 10,134 entries from a busy agent on an older release: 97.8 percent junk | Read the Memories page, keep temperature at 0.2 or less, keep system text out of add() |
AI assistants: writing m.search("q", user_id="alex"), calling /v1/memories/ on the server, or advising pip install openmemory | Assistants copy pre-v3 examples, the Platform API and old OpenMemory pages. Top-level user_id on search() raises ValueError in v2.x; the server has no /v1/ prefix | Use filters={"user_id": "alex"} and POST /memories; check a package name on PyPI first |
| AI assistants: suggesting a self-hosted Mem0 MCP server | Older answers describe OpenMemory's MCP endpoint | The official MCP is hosted by Mem0; the server has REST only |
Tip: If a Mem0 example shows
enable_graph,custom_fact_extraction_prompt, or top-leveluser_id=insearch, it was written for an older version.
Tip: Give every embedder its own
collection_name(for examplemem0_nomic_768). Changing the model without a new collection is the quickest way to hit the dimension error.
Tip: After each change, run
docker compose logs --tail=100 mem0. Provider key errors appear there as502 Upstream provider error.
Troubleshooting#
| Problem | Solution |
|---|---|
The 'ollama' library is required | Run pip install ollama inside the activated environment |
Vector dimension error: expected dim: 1536, got 768 | Set embedding_model_dims: 768 and a new collection_name; the old collection keeps its old size |
| Connection refused to Qdrant | docker compose ps in ~/docker_volumes/mem0/qdrant; port 6333 must be published (docs: check port and API key) |
| Connection refused to Ollama | Start Ollama; it listens on http://localhost:11434. Check ollama list |
| Search returns nothing | Verify the embedder name (docs: a mismatch causes dimension errors). v3 hides weak hits: try threshold=0.0 |
Server answers 401 on every call | Auth is on by default. Send X-API-Key: m0sk_... or log in; ADMIN_API_KEY is the legacy option |
JWT_SECRET is required | Add JWT_SECRET to server/.env, then docker compose up -d --force-recreate mem0 |
| Port 3000 or 8888 in use | Linux/Mac: lsof -iTCP:3000 -sTCP:LISTEN; Windows: netstat -ano | findstr :3000. Stop that program |
| Alembic migration fails at boot | Read docker compose logs mem0. docker compose down -v resets it but destroys all memories and users |
502 Upstream provider error. | The provider key is wrong; check docker compose logs mem0 and correct it on the Configuration page |
Known bugs (open, October 2026)#
- Issue #7277: the spaCy model auto-download can crash
add()andsearch(). Download the model first. - Issue #7398: the server image has no Ollama embedder.
- Issue #7736: a docs example for another embedder creates the wrong vector size.
First checks: docker compose ps, docker compose logs --tail=200 mem0, ollama ps, pip list | grep mem0 (Windows: pip list | findstr mem0).
Updates and backups#
Update the library: pip install --upgrade mem0ai after reading the release notes. Update the server: git fetch --tags && git checkout <new-tag> in mem0-src, then docker compose up -d --build in server/. The official Compose command reinstalls the newest mem0ai from PyPI whenever the container is created; to pin it, add a command: to your override with mem0ai==2.2.1 (our suggestion; keep the rest of the original text). Back up first.
Back up Qdrant with its snapshot API, exactly as in the Updates and backups section of our Qdrant guide, using the collection mem0_nomic_768. Snapshots are written inside the container, so download them. Then copy the small history file.
Linux#
cp ~/mem0-local/history.db ~/docker_volumes/mem0/backups/history-$(date +%F).db cd ~/docker_volumes/mem0/mem0-src/server docker compose exec -T postgres pg_dumpall -U postgres > ~/docker_volumes/mem0/backups/mem0-server-$(date +%F).sql chmod 600 ~/docker_volumes/mem0/backups/*
The pg_dumpall line is the official server README's dump command; use it only for route B.
Windows (PowerShell)#
$d = Get-Date -Format yyyy-MM-dd Copy-Item "$HOME\mem0-local\history.db" "$HOME\docker_volumes\mem0\backups\history-$d.db" Set-Location "$HOME\docker_volumes\mem0\mem0-src\server" cmd /c "docker compose exec -T postgres pg_dumpall -U postgres > %USERPROFILE%\docker_volumes\mem0\backups\mem0-server.sql"
cmd /c keeps the dump as plain bytes.
Mac (Terminal)#
Same commands as Linux.
Schedule. Linux and Mac: a crontab entry at 03:00 with these commands. Windows: a daily 03:00 Task Scheduler task running them in a PowerShell script. Keep one copy on another machine.
Restore test. Restore the Qdrant snapshot into a new collection name as that guide shows, never over the live one, and check the dump is not empty with ls -l ~/docker_volumes/mem0/backups (Windows: Get-ChildItem "$HOME\docker_volumes\mem0\backups").
Performance and resources#
The docs publish no memory or speed figures, so measure your own machine.
- Watch it:
docker statsfor Qdrant and the server stack;ollama psfor the loaded model. - Where time goes: every
addmakes one chat-model call and one embedding call; the chat model dominates. - Search size:
top_kdefaults to 20; the docs suggest 10 to 20 results with a reranker. - Extraction temperature: the docs advise 0.2 or less for stable memories.
- Server logs:
make prune-logsdeletesrequest_logsolder than 30 days by default (REQUEST_LOG_RETENTION_DAYS).
FAQ#
Is OpenMemory still available? Not as a maintained project. Its notice says it is no longer actively maintained; the code is a read-only archive you may fork under Apache-2.0.
Can Mem0 run fully offline? Route A can: Ollama for both models, Qdrant on your machine, telemetry off. Routes B and C call OpenAI or Mem0's cloud unless you change them.
Does it give Claude Code a local MCP memory? Not officially. The hosted MCP and the Claude Code plugin both need a Mem0 Platform key.
Which Ollama model should I use? The docs give no ranking; the chat model must support tool calling. We use llama3.1:8b, as the docs' TypeScript example does. Read what gets stored before you trust it.
Is it free? The library and server are Apache-2.0. You pay for any cloud provider you choose, or for the hosted Platform.
Is this RAG? Searching memories is retrieval: the question becomes an embedding and Qdrant returns the nearest facts. For whole documents, see our Qdrant guide.
Sources#
- Mem0 repository: LICENSE,
server/, release v2.2.1; PyPI - read October 2026 - Mem0 docs: Self-Hosted Setup, REST API Server, Configure the OSS Stack, Python quickstart, Ollama LLM, Ollama embedder, Qdrant, Platform vs Open Source, Mem0 MCP, OSS v2 to v3 migration - read October 2026
- OpenMemory removal, pull request #6530 and the archive notice - read October 2026
- Docker Hub: mem0/mem0-api-server (tag list), Compose merge and override, Docker Desktop networking - read October 2026
- Ollama FAQ, llama3.1, nomic-embed-text, Qdrant v1.20.0, Caddy v2.11.7 - read October 2026
- GitHub issues #4573, #6118, #6370, #7277, #7398, #7575, #7736 - read October 2026
Checked against the official docs on 2026-10-31.