VPS-এ mem0 self-host করতে কত RAM লাগবে
VPS-এ mem0 চালানোর প্রকৃত RAM হিসাব, localhost bind-সহ Compose file, API-র সামনে TLS এবং Ollama-তে সম্পূর্ণ local setup-এর নির্দেশনা পান।
VPS-এ mem0 নিজে চালানোর প্রকৃত RAM খরচ
mem0 নিজে চালানোর অর্থ হলো 3টি container চালানো: FastAPI memory server, pgvector extension-সহ Postgres এবং Next.js dashboard। mem0 agent-দের জন্য একটি memory layer। আপনি এতে একটি conversation পাঠান, একটি language model সেই conversation থেকে দীর্ঘস্থায়ী তথ্য বের করে, এবং পরে করা query যাতে প্রাসঙ্গিক তথ্য ফিরিয়ে আনতে পারে, সেই তথ্য vector হিসেবে সংরক্ষণ করা হয়।
3টি container-এর জন্য মোটামুটি 1 GB resident memory এবং image build হওয়ার পরে 3 থেকে 4 GB disk বরাদ্দ রাখুন। Language model অন্য কোথাও চললে 2 GB VPS-এ এটি স্বচ্ছন্দে চলে। একই মেশিনে Ollama-এর মাধ্যমে model চালালে বাকি সবকিছুর তুলনায় model-ই বেশি resource ব্যবহার করে: 4-bit-এ quantise করা একটি 8B model-এর জন্য একাই প্রায় 6 GB প্রয়োজন, তাই সম্পূর্ণ local setup-এর শুরুতেই 8 GB দরকার।
এই সংখ্যাগুলো কোনো blog post থেকে গ্রহণ করবেন না, এটিও নয়। আপনি যে stack তৈরি করেছেন, সেটির resource usage নিজে মাপুন।
docker compose ps
docker stats --no-stream
docker system df -vdocker stats প্রতিটি container-এর resident memory দেখায়। docker system df -v প্রতিটি image এবং volume কত disk ব্যবহার করছে, তা দেখায়।
Steady state কখনো peak usage নয়। docker compose up -d --build Next.js dashboard compile করে, এবং পুরো installation-এর মধ্যে সেই Node build-এই সবচেয়ে বেশি memory লাগে। 1 GB VPS-এ kernel-এর out-of-memory killer এটিকে বন্ধ করে দেয় এবং build exit code 137 দিয়ে শেষ হয়। Docker-এর bug খোঁজার আগে কারণটি নিশ্চিত করুন:
dmesg -T | grep -i "killed process"আপনার প্রয়োজনের তুলনায় কোনো server অতিরিক্ত জটিল মনে হলে ছোট বিকল্পগুলোও কার্যকর। কোনো server ছাড়াই local agent memory store এবং Claude Code-এর ভিতরেই থাকা memory—উভয়ই database ব্যবহার করে না। একাধিক agent বা একাধিক machine-এর একই memory পড়ার প্রয়োজন হলে এখানে ফিরে আসুন।
mem0-এর graph memory-এর জন্য কি Neo4j দরকার?
না। কোনো guide-এ যদি Neo4j container যোগ করতে বলা থাকে, তাহলে সেই guide বর্তমান code-এর চেয়ে পুরোনো।
mem0-এ graph memory বলতে আগে একটি external graph database বোঝানো হতো। এটি graph_store key-এর অধীনে configure করা হতো এবং enable_graph-এর মান true সেট করতে হতো। April 2026-এ প্রকাশিত নতুন memory algorithm open source SDK থেকে উভয় key সরিয়ে দিয়েছে। এখন সাধারণ add path-এর ভেতরেই entity extraction চলে। Entity-গুলো আপনার মূল collection-এর নামের শেষে _entities যোগ করে তৈরি করা দ্বিতীয় pgvector collection-এ লেখা হয়। কোনো migration চালাতে হবে না। পরবর্তী add call থেকেই built-in entity linking কাজ শুরু করে।
Graph store বাদ দিলে একটি JVM container, তার heap এবং image-এর কয়েকশো megabyte disk space সাশ্রয় হয়। 2 GB VPS-এ এর অর্থ হলো service চলবে, নাকি swapping শুরু হবে।
আপনি কী হারাচ্ছেন, তা স্পষ্টভাবে বলা যাক। আগে search result-এ relations field থাকত, যেখানে entity-গুলোর মধ্যকার edge তালিকাভুক্ত থাকত। এখন সেই field নেই। Entity match হলে combined score-এ memory-এর position বেড়ে যায়, কিন্তু traverse করার মতো কোনো structure থাকে না। আপনার application যদি ওই relationship-গুলো ব্যবহার করত, তাহলে mem0 এখন আর সেগুলো সংরক্ষণ করে না। সেক্ষেত্রে mem0-এর বাইরে আপনাকেই আলাদা graph database পরিচালনা করতে হবে এবং নিজের code দিয়ে সেখানে data পাঠাতে হবে।
রিপোজিটরিতে থাকা compose file-টি development-এর জন্য
server/docker-compose.yaml-এ name: mem0-dev ঘোষণা করা আছে এবং এটি সত্যিই তা-ই করে। এটি চালানোর আগে পড়ুন, কারণ server-এর জন্য এতে পাঁচটি সমস্যা আছে।
- এটি
server/dev.Dockerfileথেকে build করে এবং.:/appদিয়ে আপনার checkout image-এর ওপর mount করে। ফলে container-টি আপনি যে image build করেছেন তা নয়, ওই directory-তে থাকা যেকোনো কিছু চালায়। - এর command হলো
rm -rf /app/packages && pip install -q --force-reinstall --no-deps mem0ai && alembic upgrade head && uvicorn main:app --reload। এটি প্রতিবার start-এর সময় PyPI থেকেmem0aiপুনরায় install করে। ফলে upgrade করার কথা না থাকলেও restart-এর সময় server যে version চালায়, তা বদলে যেতে পারে। - একই pip ধাপের কারণে outbound network ছাড়া restart করলে uvicorn চালুর আগেই ব্যর্থ হয়। তখন PyPI-তে পৌঁছানো যায় না বলে আপনার memory server বন্ধ থাকে।
--reloaduvicorn-এর file watcher চালু করে। Code edit করলে process restart করার জন্য এটি ব্যবহৃত হয়। Production-এ এটি কোনো কার্যকর কাজ না করেই memory এবং একটি অতিরিক্ত process ব্যবহার করে। ProductionDockerfile-এরCMD-এর মধ্যেও--reloadথাকে, তাই যেকোনো অবস্থায় command override করতে হবে।- প্রকাশিত port হলো
"8888:8000","8432:5432"এবং"3000:3000"। কোনো address ছাড়া published port0.0.0.0-এ bind হয়। তাই stack চালু হওয়ার সঙ্গে সঙ্গে Postgres 8432 port-এ public internet থেকে সংযোগ গ্রহণ করে।
শেষের বিষয়টির জন্য আলাদা সতর্কতা প্রয়োজন। Docker নিজস্ব rule এমন জায়গায় লিখে যেখানে ufw পরিচালিত chain-এর আগেই তা কার্যকর হয়। তাই ufw deny 8432 published container port বন্ধ করে না। ufw-এর নিয়ম এড়িয়ে Docker কীভাবে সরাসরি port প্রকাশ করে-এ সংশ্লিষ্ট rule-গুলো ব্যাখ্যা করা হয়েছে।
একটি বাস্তব সার্ভারের জন্য compose file
server/-এর মধ্যে কাজ করুন, init-db.sh যেখানে আছে সেখানেই রাখুন, এবং docker-compose.yaml-এর জায়গায় এটি বসান।
name: mem0
services:
mem0:
build:
context: .
dockerfile: Dockerfile
restart: unless-stopped
env_file: .env
ports:
- "127.0.0.1:8888:8000"
networks: [mem0_network]
volumes:
- mem0_history:/app/history
depends_on:
postgres:
condition: service_healthy
command: >
sh -c "alembic upgrade head &&
uvicorn main:app --host 0.0.0.0 --port 8000"
environment:
- PYTHONUNBUFFERED=1
- DASHBOARD_URL=https://mem0.example.com
- APP_DB_NAME=mem0_app
- AUTH_DISABLED=false
- MEM0_TELEMETRY=false
postgres:
image: pgvector/pgvector:pg17
restart: unless-stopped
shm_size: "128mb"
networks: [mem0_network]
environment:
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}
healthcheck:
test: ["CMD-SHELL", "pg_isready -q -U ${POSTGRES_USER:-postgres}"]
interval: 5s
timeout: 5s
retries: 5
volumes:
- postgres_db:/var/lib/postgresql/data
- ./init-db.sh:/docker-entrypoint-initdb.d/init-db.sh
mem0-dashboard:
build: ./dashboard
restart: unless-stopped
ports:
- "127.0.0.1:3000:3000"
networks: [mem0_network]
environment:
- NEXT_PUBLIC_API_URL=https://mem0.example.com
- API_INTERNAL_URL=http://mem0:8000
depends_on:
mem0:
condition: service_started
volumes:
postgres_db:
mem0_history:
networks:
mem0_network:
driver: bridgeএখানে পাঁচটি পরিবর্তন গুরুত্বপূর্ণ। প্রতিটির একটি নির্দিষ্ট কারণ আছে।
প্রতিটি ports entry 127.0.0.1 দিয়ে শুরু হয়। তাই kernel এই connection-গুলো শুধু একই host থেকে গ্রহণ করে। বাইরের সব অনুরোধ reverse proxy-এর মাধ্যমে আসে। certificate শুধু reverse proxy-তেই থাকে।
Postgres-এর কোনো ports block নেই। mem0 container service name ব্যবহার করে mem0_network-এর মাধ্যমে এতে পৌঁছায়। তাই 8432 publish করলে কোনো সুবিধা নেই, বরং একটি open port তৈরি হয়। Shell প্রয়োজন হলে docker compose exec postgres psql -U postgres ব্যবহার করুন।
History এখন ./history bind mount থেকে একটি named volume-এ রাখা হয়েছে। Bind mount ডেটাকে এই host-এর একটি নির্দিষ্ট path এবং একটি নির্দিষ্ট uid-এর সঙ্গে যুক্ত করে। অন্যদিকে named volume হলো Docker-এর এমন একটি object, যেটির snapshot নেওয়া এবং সেটি সরানো যায়। কোন ক্ষেত্রে কোনটি উপযুক্ত, তা Named volume এবং bind mount-এর তুলনা-এ ব্যাখ্যা করা হয়েছে।
Command থেকে --reload বাদ দেওয়া হয়েছে এবং alembic upgrade head রাখা হয়েছে। এই migration step রাখুন। এটি না থাকলে app এমন একটি database ব্যবহার করে চালু হবে যাতে কোনো table নেই। ফলে প্রথম query-তেই প্রতিটি request ব্যর্থ হবে।
NEXT_PUBLIC_API_URL হলো আপনার browser যে URL-এ request পাঠায়। তাই এটি public HTTPS address হতে হবে, http://mem0:8000 নয়। Next.js build-এর সময় প্রতিটি NEXT_PUBLIC_ value JavaScript-এর মধ্যে স্থায়ীভাবে যুক্ত করে। তাই এটি পরিবর্তন করতে docker compose up -d --build mem0-dashboard প্রয়োজন। শুধু restart করলে JavaScript-এর মধ্যে পুরোনো value থেকেই যায় এবং dashboard ভুল host-এ request পাঠায়।
Secrets .env ফাইলে থাকে, এবং .env Internet-এর বাইরে থাকে
cd server
cp .env.example .env
openssl rand -hex 32 # paste into JWT_SECRET
openssl rand -hex 32 # paste into ADMIN_API_KEY
chmod 600 .envPOSTGRES_PASSWORD, JWT_SECRET এবং ADMIN_API_KEY সেট করুন। AUTH_DISABLED=false সেট করবেন না। ওই flag-এর নামটি তার কাজের সঠিক বর্ণনা দেয়: এটি চালু থাকলে port-এ পৌঁছাতে পারে এমন যেকোনো ব্যক্তির কাছে server তার কাছে থাকা সব memory পাঠিয়ে দেয়। onboarding event upstream-এ পাঠাতে না চাইলে MEM0_TELEMETRY=false সেট করুন।
ADMIN_API_KEY-কে X-API-Key header-এর সঙ্গে secrets.compare_digest দিয়ে তুলনা করা হয়, এবং মিল পাওয়া গেলে সব database lookup এড়িয়ে যাওয়া হয়। এটি পুরো API-এর জন্য root credential। তাই এটিকে root credential হিসেবেই পরিচালনা করুন: shell history-তে রাখবেন না, git-এ commit করবেন না, এবং prompt-এ paste করবেন না। Compose env file এবং সেগুলো থেকে secret ফাঁস হওয়ার স্থান এবং agent-এর context-এর বাইরে API key রাখা—দুটিই এখানে সরাসরি প্রযোজ্য, কারণ এই server-এর caller হলো agent।
env_file থেকে load করা value container environment-এ থাকে, এবং docker inspect সেগুলো সম্পূর্ণভাবে print করে। docker group-এর যেকোনো সদস্য সেগুলো পড়তে পারে, এবং docker group-এর যেকোনো সদস্য host-এ কার্যত root ক্ষমতা পায়।
API-কে 8888 port উন্মুক্ত না করে সামনে TLS ব্যবহার করুন
API 127.0.0.1:8888-এ এবং dashboard 127.0.0.1:3000-এ সাড়া দেয়। nginx 443 port-এ TLS (transport layer security) termination করে এবং উভয় service-এ অনুরোধ পাঠায়।
server {
listen 443 ssl;
server_name mem0.example.com;
ssl_certificate /etc/letsencrypt/live/mem0.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mem0.example.com/privkey.pem;
location ~ ^/(memories|search|configure|auth|api-keys|docs|openapi.json) {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 180s;
}
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}proxy_read_timeout দেখতে যতটা গুরুত্বপূর্ণ মনে হয়, তার চেয়েও বেশি গুরুত্বপূর্ণ। একটি add call তখন পর্যন্ত block থাকে, যতক্ষণ language model conversation পড়ে তথ্য বের করে। CPU-তে চলা একটি local 8B model-এর নিয়মিতভাবে nginx-এর 60 second default-এর চেয়ে বেশি সময় লাগে। তখন model কাজ চালিয়ে যাওয়া এবং memory লেখা সম্পন্ন হওয়া সত্ত্বেও caller 504 Gateway Time-out দেখতে পায়। ফলে এমন একটি memory তৈরি হয়, যেটি ব্যর্থ হয়েছে বলে আপনাকে জানানো হয়েছিল।
বাকি সব সংযোগ একটি default deny ufw policy দিয়ে বন্ধ করুন এবং 22 ও 443 খোলা রাখুন। nginx-এর পেছনে Ubuntu 24.04-এ certbot ব্যবহার করে certificate ইস্যু করুন। সার্ভারটি যদি ইতিমধ্যে একাধিক Compose app-এর routing করা Traefik দিয়ে অন্য app সামনে প্রকাশ করে, তাহলে দ্বিতীয় proxy ইনস্টল না করে সেই router-এ mem0 যোগ করুন।
ধোঁয়া পরীক্ষা: একটি memory যোগ করে তা পড়ে দেখুন
export MEM0_KEY='<the ADMIN_API_KEY from .env>'
curl -sS -X POST http://127.0.0.1:8888/memories \
-H "Content-Type: application/json" \
-H "X-API-Key: $MEM0_KEY" \
-d '{"messages":[{"role":"user","content":"I deploy with Docker Compose and I run Postgres 17."}],"user_id":"smoke"}'সঠিক response একটি JSON object, যাতে results list থাকে। প্রতিটি entry-তে id, extracted memory text এবং "event": "ADD" থাকে। বর্তমান algorithm শুধু ADD event ফেরত দেয়। UPDATE এবং DELETE event সরিয়ে দেওয়া হয়েছে, তাই এগুলোর অনুপস্থিতি কোনো bug নয়।
curl -sS -X POST http://127.0.0.1:8888/search \
-H "Content-Type: application/json" \
-H "X-API-Key: $MEM0_KEY" \
-d '{"query":"which database do I run?","filters":{"user_id":"smoke"},"top_k":5}'Postgres 17 সম্পর্কিত তথ্যটি score-সহ ফেরত আসা উচিত। দেখানো অনুযায়ী identifier-টি filters-এর মধ্যে দিন। একটি top-level user_id এখনও কাজ করে, এবং এটি ব্যবহার করলেই server প্রতিবার Top-level user_id in /search is deprecated. Use filters={...} instead. log করে।
কাজ শেষে cleanup করুন, যাতে test data প্রকৃত search result-কে প্রভাবিত না করে:
curl -sS -X DELETE "http://127.0.0.1:8888/memories?user_id=smoke" \
-H "X-API-Key: $MEM0_KEY"search প্রত্যাশার চেয়ে কম row ফেরত দিলে retrieval-কে দোষ দেওয়ার আগে defaults পরীক্ষা করুন। বর্তমান release-এ top_k-এর default 20, যা আগে 100 ছিল, এবং threshold-এর default none-এর পরিবর্তে 0.1। তাই দুর্বল match-গুলো এখন স্বয়ংক্রিয়ভাবে বাদ পড়ে। curl-এর মাধ্যমে এটি কাজ করলে একই endpoint-গুলো agent-এ যুক্ত করবেন, সরাসরি অথবা একই VPS-এ চলমান MCP server-এর মাধ্যমে।
OpenAI key ছাড়াই mem0 চালান
প্রথমেই বাধাটির কথা বলি, কারণ প্রথম পাঁচ মিনিটের মধ্যেই এটির মুখোমুখি হবেন। Server image-এ provider library-র একটি নির্দিষ্ট সেট থাকে, এবং /configure এই সেটের বাইরে কিছু গ্রহণ করে না:
LLM provider 'ollama' is not bundled in this image. Bundled providers: openai, anthropic, gemini. To use another provider, install its Python package, rebuild the container, and extend BUNDLED_LLM_PROVIDERS in server/main.py.কিছুই rebuild করার প্রয়োজন নেই। Ollama /v1-এ OpenAI-compatible API সরবরাহ করে, যা /v1/chat/completions এবং /v1/embeddings সমর্থন করে। mem0-এর openai provider একটি openai_base_url গ্রহণ করে। সেই key-টি Ollama-তে নির্দেশ করলে bundled check পাস করে, কারণ provider-টি সত্যিই openai। শুধু address পরিবর্তিত হয়।
একই Compose project-এ Ollama যোগ করুন:
ollama:
image: ollama/ollama
restart: unless-stopped
networks: [mem0_network]
ports:
- "127.0.0.1:11434:11434"
volumes:
- ollama_models:/root/.ollamaTop-level volumes: key-এর অধীনে ollama_models: যোগ করুন। এরপর একটি chat model এবং একটি embedding model pull করুন:
docker compose up -d ollama
docker compose exec ollama ollama pull llama3.1:8b
docker compose exec ollama ollama pull nomic-embed-textOllama যদি ইতিমধ্যে host-এ systemd unit হিসেবে চলে, যেমন VPS-এ সরাসরি Ollama চালানো, তাহলে container-কে 127.0.0.1:11434-এ নির্দেশ করবেন না। mem0 container-এর ভিতরে 127.0.0.1 হলো mem0 container। mem0 service-কে extra_hosts: ["host.docker.internal:host-gateway"] দিন, systemd drop-in-এ Environment="OLLAMA_HOST=0.0.0.0:11434" সেট করুন যাতে Ollama bridge যে address-এ পৌঁছাতে পারে সেখানে listen করে, এবং firewall-এ 11434 বন্ধ রাখুন।
কিছু configure করার আগে model-এর embedding dimension জিজ্ঞাসা করুন
এই একটি ধাপেই retrieval আদৌ কাজ করবে কি না নির্ধারিত হয়।
mem0-এর pgvector store একটি নির্দিষ্ট vector width, vector vector(1536), ব্যবহার করে table তৈরি করে, কারণ embedding_model_dims-এর default মান 1536, যা OpenAI-এর text-embedding-3-small-এর width। nomic-embed-text 768টি value ফেরত দেয়। mem0-এর ভিতরে এই দুই সংখ্যার তুলনা হয় না। তাই প্রথম insert-এর সময় Postgres থেকে mismatch-এর error আসে:
expected 1536 dimensions, not 768এই paragraph-এর সংখ্যাটিও যাচাই না করে বিশ্বাস করবেন না। Model-কে জিজ্ঞাসা করুন:
curl -sS http://127.0.0.1:11434/v1/embeddings \
-H "Content-Type: application/json" \
-d '{"model":"nomic-embed-text","input":"dimension check"}' \
| python3 -c "import json,sys; print(len(json.load(sys.stdin)['data'][0]['embedding']))"এতে আপনার collection-এ যে width ব্যবহার করতে হবে, তা দেখা যাবে। Configuration একটি file-এ লিখুন, কারণ shell quoting-এর মাধ্যমে Postgres password paste করলেই production-এ typo ঢুকে পড়ে।
{
"vector_store": {
"provider": "pgvector",
"config": {
"host": "postgres",
"port": 5432,
"dbname": "postgres",
"user": "postgres",
"password": "<POSTGRES_PASSWORD from .env>",
"collection_name": "memories_local_768",
"embedding_model_dims": 768
}
},
"llm": {
"provider": "openai",
"config": {
"model": "llama3.1:8b",
"api_key": "ollama",
"openai_base_url": "http://ollama:11434/v1",
"temperature": 0.2
}
},
"embedder": {
"provider": "openai",
"config": {
"model": "nomic-embed-text",
"api_key": "ollama",
"openai_base_url": "http://ollama:11434/v1"
}
}
}curl -sS -X POST http://127.0.0.1:8888/configure \
-H "Content-Type: application/json" \
-H "X-API-Key: $MEM0_KEY" \
-d @config.json
curl -sS http://127.0.0.1:8888/configure -H "X-API-Key: $MEM0_KEY"দ্বিতীয় call-টি configuration পড়ে দেখায়। এতে বোঝা যায় write সফলভাবে হয়েছে কি না। এরপর উপরের smoke test আবার চালান।
এই JSON-এর চারটি বিষয় স্পষ্ট নয়। প্রতিটি ভুল হলে আলাদা সমস্যা হবে।
api_key হলো ollama string, এবং Ollama এর value উপেক্ষা করে। এটি empty হতে পারবে না, কারণ কোনো key সেট না থাকলে request process ছাড়ার আগেই OpenAI client library error দেয়। যেকোনো non-empty string কাজ করবে।
embedding_model_dims vector store-এ দিতে হবে। Embedder-এ ইচ্ছাকৃতভাবে কোনো embedding_dims নেই। আপনি embedding_dims সেট করলেই mem0 OpenAI-এর dimensions parameter পাঠায়। Matryoshka truncation বাস্তবায়ন না করা backend-গুলো এই parameter সরাসরি প্রত্যাখ্যান করে। Table তৈরি করার সময় width সেট করুন এবং embedder অপরিবর্তিত রাখুন।
collection_name নতুন। mem0 CREATE TABLE IF NOT EXISTS দিয়ে table তৈরি করে। তাই কোনো existing collection-এ ভিন্ন width নির্দেশ করলেও কিছুই পরিবর্তিত হয় না: পুরোনো vector(1536) column থেকে যায় এবং প্রতিটি insert ব্যর্থ হয়। Width পরিবর্তনের জন্য নতুন collection name ব্যবহার করতে হবে, অথবা হাতে পুরোনো table drop করতে হবে।
openai_base_url-এর host হলো Compose service name ollama, localhost নয়। Shared network-এ container-গুলো service name ব্যবহার করে একে অপরকে resolve করে।
সম্পূর্ণ local path-এর খরচ
Quality সম্পর্কে নিজের কাছে সৎ থাকুন। mem0-এর প্রকাশিত benchmark score-গুলো extraction-এর জন্য frontier model ব্যবহার করে মাপা হয়েছে। তাই VPS-এ চলা 8B model-এর জন্য এগুলোকে forecast নয়, বরং ceiling হিসেবে বিবেচনা করুন। ছোট model আরও অস্পষ্ট fact লিখতে পারে। কখনও JSON চাওয়া হলেও prose ফেরত দেয়। এর ফলে কোনো error ছাড়াই add call থেকে empty results list ফেরত আসতে পারে।
Speed হলো অন্য খরচ। CPU-only extraction-এ প্রতিটি add call-এ কয়েক সেকেন্ড লাগে। আপনি যে প্রতিটি message store করেন, তার জন্য এই খরচ দিতে হয়। এই latency গুরুত্বপূর্ণ হলে GPU-যুক্ত একটি VPS ব্যবহার করাই সঠিক সমাধান। 8B model-এ আরও CPU core যোগ করলে মানুষের প্রত্যাশার তুলনায় অনেক কম উন্নতি হয়।
আপনি যা-ই বেছে নিন, একটি নিয়ম সব সময় প্রযোজ্য: একই collection-এর মধ্যে কখনও embedding model মিশিয়ে ব্যবহার করবেন না। একই width ভাগ করে এমন দুটি ভিন্ন model এমন vector তৈরি করে, যেগুলো পরস্পরের সঙ্গে তুলনীয় নয়। Insert সফল হয়, search row ফেরত দেয়, কিন্তু row-গুলো ভুল হয়। কোথাও কোনো error রিপোর্ট হয় না।
ব্যাকআপ: একটি নয়, দুটি database আছে
mem0-এর ব্যাকআপ নেওয়ার সময় সবচেয়ে সাধারণ ভুল হলো একটি মাত্র database dump করা। init-db.sh ডিফল্ট postgres database-এর পাশাপাশি mem0_app তৈরি করে, এবং দুটিতে ভিন্ন ধরনের তথ্য থাকে। postgres database-এ pgvector collection থাকে, যেগুলো memories। mem0_app-এ users, sessions, API keys এবং request logs থাকে।
শুধু postgres restore করলে memories ফিরে আসবে, কিন্তু প্রতিটি account এবং API key হারিয়ে যাবে। ফলে সেগুলো পড়ার জন্য কোনো কিছুই authenticate করতে পারবে না। একই command-এ roles-সহ দুটি database-ই dump করুন:
docker compose exec -T postgres pg_dumpall -U postgres --clean \
| gzip > "mem0-$(date +%F).sql.gz"history volume Postgres থেকে আলাদা এবং এর নিজস্ব copy প্রয়োজন:
docker run --rm -v mem0_mem0_history:/data -v "$PWD:/backup" \
alpine tar czf /backup/mem0-history.tgz -C /data .Docker project name দিয়ে volume-এর নামের আগে prefix যোগ করে। তাই mem0_mem0_history ধরে নেওয়ার আগে docker volume ls দিয়ে নিজের volume-এর নাম নিশ্চিত করুন।
কোনো backup সম্পূর্ণ নির্ভরযোগ্য ধরে নেওয়ার আগে সেটি একটি scratch container-এ restore করে row count পরীক্ষা করুন:
gunzip -c mem0-2026-08-03.sql.gz \
| docker compose exec -T postgres psql -U postgres -d postgresযে backup কখনো restore করে পরীক্ষা করা হয়নি, সেটি কেবল অনুমান। dump সঠিক হওয়ার পরে off-site storage-এ restic snapshots ব্যবহার করে সেগুলো server-এর বাইরে পাঠান, কারণ যে server-কে সুরক্ষিত করার জন্য backup নেওয়া হয়েছে, সেই server-এ backup রেখে কোনো সুরক্ষা পাওয়া যায় না।
ব্যর্থতার ধরন এবং আপনি যে নির্দিষ্ট বার্তাগুলো দেখবেন
{"detail":"Authentication required. Provide a Bearer token or X-API-Key header."} বোঝায় যে header অনুপস্থিত বা ভুল বানানে লেখা হয়েছে। নামটি X-API-Key, এবং curl header-এর নাম হুবহু পাঠায়।
কোনো add অপারেশনে {"detail":"At least one identifier (user_id, agent_id, run_id) is required."} দেখা গেলে বোঝায় যে request-এ এগুলোর একটিও ছিল না। একটি memory-কে কোনো কিছুর scope-এর মধ্যে রাখতে হয়, কারণ search filter ঠিক ওই field-গুলোর ওপর কাজ করে।
HTTP 400-এর সঙ্গে LLM provider 'ollama' is not bundled in this image দেখা গেলে বোঝায় যে আপনি "provider": "ollama" পাঠিয়েছেন। openai_base_url-কে Ollama-র দিকে নির্দেশ করে "provider": "openai" ব্যবহার করুন।
Postgres থেকে expected 1536 dimensions, not 768 দেখা গেলে বোঝায় যে collection একটি width-এ তৈরি হয়েছিল, কিন্তু embedder অন্য width ফেরত দিচ্ছে। vector store-এ embedding_model_dims সেট করুন এবং নতুন collection_name ব্যবহার করুন।
কোনো error ছাড়াই model পরিবর্তনের পরে Search returns rows that make no sense দেখা গেলে width এখনও মিলে যাচ্ছে। তাই database কোনো সমস্যা দেখছে না, কিন্তু দুটি model একই sentence-কে ভিন্ন অবস্থানে রাখে। নতুন collection শুরু করে আবার add করুন।
Ollama-তে সংযোগ করার সময় mem0 log-এ Connection refused দেখা গেলে সাধারণত openai_base_url-এ 127.0.0.1 বোঝায়। container-এর ভেতর ওই address-টি container-কেই নির্দেশ করে। service name ব্যবহার করুন, অথবা Ollama host machine-এ চললে host gateway ব্যবহার করুন।
কোনো add অপারেশনে nginx থেকে 504 Gateway Time-out দেখা গেলে বোঝায় যে model-এর কাজ proxy_read_timeout-এর চেয়ে বেশি সময় নিয়েছে। timeout বাড়ান এবং request আবার পাঠানোর আগে memory লেখা হয়েছিল কি না পরীক্ষা করুন।
docker compose up --build চলার সময় exit code 137 দেখা গেলে বোঝায় যে out-of-memory killer dashboard build বন্ধ করেছে। swap যোগ করুন, অথবা বড় machine-এ image build করে registry-তে push করুন।
error: port 3000 is already in use repo-র make up target থেকে আসে। 3000 বা 8888 port ব্যবহৃত থাকলে এটি start হতে অস্বীকার করে। lsof -iTCP:3000 -sTCP:LISTEN দিয়ে কোন process portটি ব্যবহার করছে তা খুঁজে বের করুন।
FAQ
graph memory সহ mem0 চালাতে কি এখনও Neo4j দরকার?
না। April 2026-এ প্রকাশিত নতুন memory algorithm open source SDK থেকে graph_store এবং enable_graph configuration key সরিয়ে দিয়েছে। এখন স্বাভাবিক add operation চলার সময় entity extraction হয় এবং <collection_name>_entities নামের দ্বিতীয় pgvector collection-এ data লেখা হয়। তাই কোনো external graph database, অতিরিক্ত container বা migration step দরকার নেই। এর বিনিময়ে search result-এ relations field আর থাকে না। এখন entity memory-র ranking বাড়ায়, traverse করার জন্য edge দেয় না। তাই কোনো application যদি ওই relationship ধরে কাজ করত, তাহলে mem0-এর বাইরে নিজস্ব graph store ব্যবহার করতে হবে।
self-hosted mem0 server চালানোর জন্য সবচেয়ে ছোট VPS কোনটি?
Language model অন্যত্র host করা থাকলে API container, Postgres এবং dashboard চালানোর জন্য 2 GB RAM এবং প্রায় 4 GB free disk যথেষ্ট। প্রথম build-এর সময় resource চাপ সবচেয়ে বেশি হয়, কারণ Next.js dashboard compile করতে এটি চালানোর চেয়ে বেশি memory ব্যবহার করে। 1 GB-এর server-এ build process exit code 137-এর কারণে বন্ধ হয়ে যায়। Ollama একই server-এ চালালে model অনুযায়ী server-এর আকার নির্ধারণ করুন। 4-bit quantisation-সহ একটি 8B model-এর জন্য একাই প্রায় 6 GB লাগে। তাই 8 GB RAM পরিকল্পনা করুন।
OpenAI API key ছাড়া কি mem0 চালানো যায়?
হ্যাঁ, Ollama-এর OpenAI-compatible endpoint ব্যবহার করে চালানো যায়। "provider": "ollama" সেট করলে কাজ ব্যর্থ হয়, কারণ server image-এ শুধু openai, anthropic এবং gemini library bundled থাকে এবং HTTP 400 ফেরত দেয়। এর পরিবর্তে "provider": "openai" অপরিবর্তিত রাখুন এবং llm ও embedder—উভয়ের জন্য যেকোনো non-empty api_key দিয়ে "openai_base_url": "http://ollama:11434/v1" সেট করুন। Ollama key উপেক্ষা করে। Bundled provider check-ও পাস করে, কারণ provider প্রকৃতপক্ষে openai।
Local embedding model-এ পরিবর্তন করার পরে mem0 কোনো result ফেরত দেয় না কেন?
কারণ pgvector table-টি নির্দিষ্ট width নিয়ে তৈরি হয়েছিল। embedding_model_dims-এর default 1536, কিন্তু nomic-embed-text 768 ফেরত দেয়। ফলে Postgres expected 1536 dimensions, not 768 সহ insert প্রত্যাখ্যান করে। mem0 CREATE TABLE IF NOT EXISTS ব্যবহার করে table তৈরি করে। তাই শুধু সংখ্যাটি পরিবর্তন করলে existing collection-এ কোনো প্রভাব পড়ে না। আপনার model-এর প্রকৃত width অনুযায়ী embedding_model_dims সেট করুন। /v1/embeddings call করে এবং সেটি ফেরত দেওয়া value গুনে width নিশ্চিত করুন। একই সময়ে vector store-এর জন্য নতুন collection_name দিন।