SSD Nodes Learn 🎉 VPS $5.50/महिन्यापासून
मार्गदर्शक Matt Connorद्वारे Matt Connor · अपडेटेड 2026-08-13

VPS वर mem0 स्वयं-होस्ट करण्यासाठी किती RAM लागते?

VPS वर mem0 memory server चालवण्याचा प्रत्यक्ष RAM खर्च, localhost ला bind करणारी Compose file, API समोरील TLS आणि Ollama सह पूर्णपणे local मार्ग जाणून घ्या.

VPS वर mem0 स्वयं-होस्ट करण्यासाठी प्रत्यक्षात किती RAM लागते

mem0 स्वयं-होस्ट करण्यासाठी तीन containers चालवावे लागतात: FastAPI memory server, pgvector extension असलेले Postgres आणि Next.js dashboard. mem0 हा agents साठी memory layer आहे. तुम्ही त्याला conversation पाठवता. Language model त्या conversation मधून टिकणारी तथ्ये वेगळी काढतो. नंतरच्या query मधून संबंधित तथ्ये परत मिळवता यावीत म्हणून ती vectors म्हणून साठवली जातात.

तीन containers साठी resident memory म्हणून साधारण 1 GB आणि images build केल्यानंतर disk वर 3 ते 4 GB जागा गृहीत धरा. Language model दुसऱ्या ठिकाणी चालत असेल, तर 2 GB VPS वर ही रचना सहज चालते. Model त्याच मशीनवर Ollama द्वारे चालवत असल्यास बाकी सर्वांच्या तुलनेत model ची गरज सर्वाधिक असते. 4 bits वर quantise केलेल्या 8B model ला स्वतंत्रपणे सुमारे 6 GB RAM लागते. त्यामुळे पूर्णपणे local रचना किमान 8 GB RAM पासून सुरू होते.

या आकड्यांवर कोणत्याही blog post वर, यासह, अवलंबून राहू नका. तुम्ही प्रत्यक्षात तयार केलेल्या stack चे मोजमाप करा.

docker compose ps
docker stats --no-stream
docker system df -v

docker stats प्रत्येक container ची resident memory दाखवते. docker system df -v प्रत्येक image आणि प्रत्येक volume ने व्यापलेली disk जागा दाखवते.

Steady state म्हणजे peak वापर नव्हे. docker compose up -d --build Next.js dashboard compile करते. या संपूर्ण installation मधील सर्वाधिक memory वापराचा टप्पा हा Node build असतो. 1 GB VPS वर kernel चा out-of-memory killer ही process थांबवतो आणि build exit code 137 सह संपते. Docker मधील bug शोधण्यापूर्वी कारणाची खात्री करा:

dmesg -T | grep -i "killed process"

तुमच्या गरजेच्या तुलनेत server ची रचना जास्त मोठी वाटत असल्यास, लहान पर्याय उपलब्ध आहेत. server शिवाय local agent memory store आणि Claude Code मध्येच साठवली जाणारी memory हे दोन्ही database वापरत नाहीत. अनेक agents किंवा अनेक machines ना समान memories वाचण्याची गरज भासल्यास येथे परत या.

mem0 graph memory साठी Neo4j आवश्यक आहे का?

नाही. एखाद्या मार्गदर्शिकेत Neo4j container जोडण्यास सांगितले असेल, तर ती मार्गदर्शिका सध्याच्या code पेक्षा जुनी आहे.

mem0 मधील graph memory चा अर्थ पूर्वी बाह्य graph database असा होता. तो graph_store key अंतर्गत configure केला जात असे आणि enable_graph true वर सेट करावे लागत असे. एप्रिल 2026 मध्ये release झालेल्या नवीन memory algorithm ने open source SDK मधून दोन्ही keys काढून टाकले. आता entity extraction नेहमीच्या add path मध्येच चालते. Entities तुमच्या मुख्य collection च्या नावावरून तयार केलेल्या आणि त्याला _entities जोडलेल्या दुसऱ्या pgvector collection मध्ये लिहिल्या जातात. कोणतेही migration चालवण्याची गरज नाही. Built-in entity linking पुढील add call पासून कार्य करू लागते.

Graph store काढून टाकल्याने JVM container, त्याची heap आणि image मधील काहीशे megabytes वाचतात. 2 GB VPS वर यामुळे सेवा चालू राहणे आणि swapping सुरू होणे यांत फरक पडतो.

यामुळे नेमके काय गमावले जाते ते स्पष्टपणे सांगायचे तर: पूर्वी search results मध्ये entities मधील edges ची यादी देणारे relations field असायचे. ते field आता नाही. Entity matches आता combined score मध्ये memory चे स्थान वाढवतात; मात्र traverse करता येईल अशी कोणतीही structure उपलब्ध नाही. तुमच्या application ने त्या relationships वर प्रक्रिया केली असेल, तर mem0 मध्ये त्या आता साठवल्या जात नाहीत. अशा वेळी mem0 च्या बाहेर स्वतःचे graph database ठेवावे आणि तुमच्या code द्वारे त्यात data भरावा.

रेपॉझिटरीमधील compose फाइल development compose आहे

server/docker-compose.yaml मध्ये name: mem0-dev घोषित केले आहे आणि त्याचा परिणामही तसाच होतो. ती फाइल चालवण्यापूर्वी वाचा, कारण सर्व्हरसाठी त्यामध्ये पाच समस्या आहेत.

  • ती server/dev.Dockerfile पासून build करते आणि .:/app वापरून तुमचा checkout image वर mount करते. त्यामुळे container तुम्ही build केलेले चालवण्याऐवजी त्या directory मध्ये जे आहे ते चालवतो.
  • तिची command rm -rf /app/packages && pip install -q --force-reinstall --no-deps mem0ai && alembic upgrade head && uvicorn main:app --reload आहे. त्यामुळे प्रत्येक वेळी सुरू होताना PyPI वरून mem0ai पुन्हा install होते. परिणामी upgrade करायचा हेतू नसलेल्या restart दरम्यानही सर्व्हरवर चालणारी version बदलू शकते.
  • त्याच pip step मुळे outbound network उपलब्ध नसताना केलेला restart uvicorn सुरू होण्यापूर्वीच fail होतो. PyPI पर्यंत पोहोचता न आल्यामुळे तुमचा memory server बंद राहतो.
  • --reload मुळे uvicorn चा file watcher सुरू होतो. तुम्ही code संपादित केल्यावर process पुन्हा सुरू करण्यासाठी तो वापरला जातो. Production मध्ये त्याचा उपयोग नसतो आणि तो memory तसेच दुसरा process वापरतो. Production Dockerfile मध्येही --reload हे CMD मध्ये आहे. त्यामुळे कोणत्याही परिस्थितीत command override करावी लागते.
  • प्रकाशित ports "8888:8000", "8432:5432" आणि "3000:3000" आहेत. Port च्या आधी address दिलेला नसल्यास तो 0.0.0.0 ला bind होतो. त्यामुळे stack सुरू होताच Postgres 8432 वर public internet ला उपलब्ध होतो.

या शेवटच्या मुद्द्यासाठी स्वतंत्र इशारा आवश्यक आहे. Docker स्वतःचे rules ufw व्यवस्थापित करत असलेल्या chain च्या आधी ठेवून port publish करते. त्यामुळे ufw deny 8432 published container port बंद करत नाही. Docker ports थेट ufw च्या पलीकडे publish करते यामध्ये संबंधित rules स्पष्ट केले आहेत.

प्रत्यक्ष सर्व्हरसाठी compose फाइल

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 नोंद 127.0.0.1 पासून सुरू होते. त्यामुळे kernel ही connections फक्त त्याच मशीनकडून स्वीकारतो. बाहेरून येणारी प्रत्येक गोष्ट reverse proxy मार्फत येते. certificate धारण करणारी हीच एकमेव सेवा आहे.

Postgres मध्ये ports block मुळीच नाही. mem0 container mem0_network द्वारे service name वापरून त्याच्यापर्यंत पोहोचतो. त्यामुळे 8432 publish केल्याने काही लाभ होत नाही आणि एक उघडा port मात्र वाढतो. Shell आवश्यक असेल तेव्हा docker compose exec postgres psql -U postgres वापरा.

History आता ./history bind mount ऐवजी named volume मध्ये ठेवली जाते. Bind mount मुळे data या host वरील एका path आणि एका uid शी बांधला जातो. Named volume हे Docker snapshot करून हलवू शकणारी object असते. Named volumes आणि bind mounts यापैकी कोणता पर्याय कधी योग्य आहे हे स्पष्ट करते.

Command मधून --reload काढले आहे आणि alembic upgrade head ठेवले आहे. Migration step ठेवणे आवश्यक आहे. ते नसल्यास app tables नसलेल्या database विरुद्ध सुरू होते आणि पहिल्याच query वर प्रत्येक request अपयशी ठरते.

NEXT_PUBLIC_API_URL हा browser कडून call केला जाणारा URL आहे. त्यामुळे तो सार्वजनिक HTTPS address असला पाहिजे; http://mem0:8000 नसावा. Next.js प्रत्येक NEXT_PUBLIC_ value build time ला inline करते. त्यामुळे ती बदलण्यासाठी docker compose up -d --build mem0-dashboard आवश्यक आहे. साधा restart केल्यास JavaScript मध्ये जुनी valueच अंतर्भूत राहते आणि dashboard चुकीच्या host ला call करते.

Secrets .env मध्ये असतात आणि .env इंटरनेटवर उपलब्ध नसतो

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 .env

POSTGRES_PASSWORD, JWT_SECRET आणि ADMIN_API_KEY सेट करा. AUTH_DISABLED=false तसाच ठेवा. त्या flag चे नाव त्याचे कार्य स्पष्टपणे सांगते: तो सुरू असल्यास, पोर्टपर्यंत पोहोचू शकणाऱ्या कोणालाही सर्व्हरकडे असलेली प्रत्येक memory तो देते. Onboarding event upstream कडे पाठवायचा नसेल, तर MEM0_TELEMETRY=false सेट करा.

ADMIN_API_KEY ची तुलना X-API-Key header शी secrets.compare_digest वापरून केली जाते. जुळणी झाल्यास database lookup पूर्णपणे वगळले जातात. हे संपूर्ण API साठी root credential आहे. त्यानुसारच ते हाताळा: shell history मध्ये ठेवू नका, git मध्ये commit करू नका आणि prompt मध्ये paste करू नका. Compose env files आणि त्यांमधून secrets कुठे बाहेर पडतात आणि agent च्या context मधून API keys दूर ठेवणे हे दोन्ही येथे थेट लागू होतात, कारण या सर्व्हरला call करणारे agents आहेत.

env_file मधून load केलेली values container environment मध्ये राहतात आणि docker inspect त्या पूर्णपणे दाखवते. docker group मधील कोणतीही व्यक्ती त्या वाचू शकते आणि docker group मधील कोणतीही व्यक्ती host वर प्रभावीपणे root असते.

API समोर TLS ठेवा; 8888 सार्वजनिकपणे उघडू नका

API 127.0.0.1:8888 वर आणि dashboard 127.0.0.1:3000 वर प्रतिसाद देते. nginx 443 वर TLS (transport layer security) termination करते आणि दोन्हींकडे विनंत्या पाठवते.

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 थांबते. CPU वर चालणाऱ्या स्थानिक 8B मॉडेलला nginx च्या 60 सेकंदांच्या default पेक्षा नियमितपणे जास्त वेळ लागतो. त्यामुळे मॉडेल अजूनही काम करत असताना आणि memory मध्ये नोंद होत असतानाही caller ला 504 Gateway Time-out दिसते. परिणामी, अपयशी असल्याचे सांगितलेली memory प्रत्यक्षात तयार होते.

उर्वरित प्रवेश default deny ufw धोरणाने बंद करा आणि 22 व 443 खुले ठेवा. nginx मागे Ubuntu 24.04 वर certbot वापरून certificate जारी करा. या server वर इतर अॅप्स आधीच अनेक Compose अॅप्सचे routing करणाऱ्या Traefik द्वारे प्रकाशित होत असतील, तर दुसरा proxy स्थापित करण्याऐवजी mem0 त्याच router मध्ये जोडा.

एक memory जोडून ती परत वाचणे: smoke test

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 हा results list असलेला JSON object असतो. प्रत्येक entry मध्ये id, काढलेला memory मजकूर आणि "event": "ADD" असतो. सध्याचा algorithm केवळ ADD events परत करतो. UPDATE आणि DELETE events काढून टाकण्यात आले आहेत. त्यामुळे ते नसणे हा 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 विषयीचा fact score सह परत यायला हवा. दाखवल्याप्रमाणे identifier filters मध्ये द्या. Top-level user_id अजूनही कार्य करते आणि ते वापरल्यावर server प्रत्येक वेळी Top-level user_id in /search is deprecated. Use filters={...} instead. log करतो.

Test data मुळे प्रत्यक्ष searches वर परिणाम होऊ नये म्हणून वापरानंतर ते साफ करा:

curl -sS -X DELETE "http://127.0.0.1:8888/memories?user_id=smoke" \
  -H "X-API-Key: $MEM0_KEY"

Search ने अपेक्षेपेक्षा कमी rows परत केल्यास retrieval ला दोष देण्यापूर्वी defaults तपासा. सध्याच्या release मध्ये top_k चे default 20 आहे; ते पूर्वीच्या 100 पेक्षा कमी आहे. threshold चे default none ऐवजी 0.1 आहे. त्यामुळे कमकुवत matches आता आपोआप filter होतात. हे curl द्वारे कार्य करू लागल्यानंतर, agent मध्ये जोडण्यासाठी हेच endpoints वापरा—थेट किंवा त्याच VPS वर चालणाऱ्या MCP server द्वारे.

mem0 पूर्णपणे OpenAI key शिवाय चालवा

सर्वप्रथम अडथळा समजून घ्या, कारण पहिल्या पाच मिनिटांतच तो दिसेल. सर्व्हर इमेजमध्ये provider libraries चा निश्चित संच समाविष्ट असतो आणि /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-सुसंगत 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/.ollama

वरच्या स्तरावरील 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-text

जर Ollama 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"] द्या. Ollama bridge कडून पोहोचता येईल अशा address वर ऐकेल यासाठी systemd drop-in मध्ये Environment="OLLAMA_HOST=0.0.0.0:11434" सेट करा. Firewall मध्ये 11434 बंदच ठेवा.

काहीही configure करण्यापूर्वी model ची embedding dimension विचारा

हा एक टप्पा retrieval प्रत्यक्षात कार्य करेल की नाही हे ठरवतो.

mem0 चा pgvector store निश्चित vector width, vector vector(1536), वापरून table तयार करतो, कारण embedding_model_dims ची default value 1536 आहे. ही OpenAI च्या text-embedding-3-small ची width आहे. nomic-embed-text 768 values परत करते. mem0 मध्ये या दोन संख्यांची तुलना करणारी कोणतीही तपासणी नाही. त्यामुळे पहिल्या insert वेळी Postgres कडून mismatch दिसतो:

expected 1536 dimensions, not 768

या परिच्छेदातील संख्येवरही विश्वास ठेवू नका. 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 फाइलमध्ये लिहा, कारण shell quoting मधून Postgres password paste केल्याने production मध्ये चुका जाण्याची शक्यता असते.

{
  "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 दुर्लक्षित करते. ती रिकामी ठेवता येत नाही, कारण 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 लागू न करणारे backends हा parameter थेट नाकारतात. Table तयार करताना width सेट करा आणि embedder मध्ये कोणताही बदल करू नका.

collection_name नवीन आहे. mem0 CREATE TABLE IF NOT EXISTS वापरून table तयार करते. त्यामुळे विद्यमान collection कडे वेगळी width निर्देशित केली तरी काहीही बदलत नाही: जुना vector(1536) column तसाच राहतो आणि प्रत्येक insert अयशस्वी होतो. Width बदलण्यासाठी नवीन collection name वापरा किंवा जुना table manually drop करा.

openai_base_url मधील host हा Compose service name ollama आहे, localhost नाही. Shared network वर containers एकमेकांना service name ने resolve करतात.

पूर्णपणे स्थानिक मार्गाची किंमत

Quality बाबत स्वतःशी प्रामाणिक रहा. mem0 चे प्रकाशित benchmark scores extraction साठी frontier models वापरून मोजले गेले आहेत. त्यामुळे VPS वरील 8B model साठी ते अंदाज न मानता कमाल मर्यादा समजा. लहान model अधिक अस्पष्ट facts लिहितो. कधी कधी JSON मागितले असतानाही prose परत करतो. याचा परिणाम error शिवाय empty results list परत करणाऱ्या add call मध्ये दिसतो.

Speed ही दुसरी किंमत आहे. CPU-only extraction ला प्रत्येक add call साठी काही सेकंद लागतात आणि store केलेल्या प्रत्येक message साठी ही किंमत मोजावी लागते. हा latency महत्त्वाचा असल्यास GPU जोडलेला VPS हा योग्य उपाय आहे. 8B model ला अधिक CPU cores दिल्याने अपेक्षेपेक्षा खूपच कमी फायदा होतो.

तुमची निवड कोणतीही असो, एक नियम कायम लागू आहे: एका collection मध्ये embedding models कधीही मिसळू नका. समान width असलेले दोन वेगवेगळे models vectors तयार करू शकतात, परंतु ते परस्पर तुलनीय नसतात. Insert यशस्वी होतो, search rows परत करते आणि त्या rows चुकीच्या असतात. कुठेही error नोंदवला जात नाही.

बॅकअप: एक नव्हे, दोन databases आहेत

mem0 च्या बॅकअपमध्ये सर्वात सामान्य चूक म्हणजे एकच database dump करणे. init-db.sh default postgres database च्या बाजूला mem0_app तयार करते आणि दोन्हीमध्ये वेगवेगळी माहिती असते. postgres database मध्ये pgvector collections असतात. याच collections म्हणजे memories. mem0_app मध्ये users, sessions, API keys आणि request logs असतात.

फक्त postgres restore केल्यास memories परत येतात; परंतु प्रत्येक account आणि API key नष्ट झालेली असते. त्यामुळे ती वाचण्यासाठी authentication करता येत नाही. एकाच command मध्ये दोन्ही databases आणि roles 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 volume names च्या आधी project name लावते. त्यामुळे mem0_mem0_history गृहीत धरण्यापूर्वी docker volume ls ने तुमचे volume name निश्चित करा.

Scratch container मध्ये restore करा आणि त्यावर विश्वास ठेवण्यापूर्वी row counts तपासा:

gunzip -c mem0-2026-08-03.sql.gz \
  | docker compose exec -T postgres psql -U postgres -d postgres

ज्याचा restore कधीच तपासलेला नाही असा backup म्हणजे केवळ अंदाज. Dumps योग्य असल्याची खात्री झाल्यावर ते box च्या बाहेर restic snapshots off-site storage वर पाठवा. ज्या server चे संरक्षण करायचे आहे त्याच server वर असलेला backup कोणत्याही गोष्टीचे संरक्षण करत नाही.

अपयशाच्या स्थिती आणि तुम्हाला दिसणारे अचूक strings

{"detail":"Authentication required. Provide a Bearer token or X-API-Key header."} म्हणजे header अनुपस्थित आहे किंवा चुकीचा लिहिला आहे. नाव X-API-Key आहे आणि curl header names जसेच्या तसे पाठवतो.

{"detail":"At least one identifier (user_id, agent_id, run_id) is required."} add करताना दिसल्यास request मध्ये यापैकी एकही field नव्हता. Memory एखाद्या गोष्टीशी scoped असणे आवश्यक आहे, कारण search नेमक्या या fields वर filter करते.

LLM provider 'ollama' is not bundled in this image आणि HTTP 400 म्हणजे तुम्ही "provider": "ollama" पाठवले. Ollama कडे निर्देश करणारे openai_base_url वापरून "provider": "openai" वापरा.

expected 1536 dimensions, not 768 Postgres कडून आल्यास collection एका width वर तयार झाला होता आणि embedder दुसरी width परत करतो. Vector store वर embedding_model_dims सेट करा आणि नवीन collection_name वापरा.

Model बदलल्यानंतर Search returns rows that make no sense आणि कुठेही error दिसत नसेल, तर width अजूनही जुळत आहे. त्यामुळे database ला समस्या दिसत नाही. मात्र दोन models एकाच sentence ला वेगवेगळ्या positions मध्ये ठेवतात. नवीन collection सुरू करा आणि entries पुन्हा add करा.

Ollama पर्यंत पोहोचताना mem0 logs मध्ये Connection refused दिसणे म्हणजे साधारणपणे openai_base_url मधील 127.0.0.1 असते. Container च्या आत तो address container कडे निर्देश करतो. Ollama host वर चालत असल्यास service name किंवा host gateway वापरा.

add करताना nginx कडून 504 Gateway Time-out मिळाल्यास model ला proxy_read_timeout पेक्षा जास्त वेळ लागला. ही मर्यादा वाढवा आणि request पुन्हा पाठवण्यापूर्वी memory लिहिली गेली आहे का ते तपासा.

exit code 137 during docker compose up --build म्हणजे out-of-memory killer dashboard build थांबवत आहे. Swap जोडा किंवा image मोठ्या machine वर build करून registry मध्ये push करा.

error: port 3000 is already in use repo च्या make up target कडून येते. 3000 किंवा 8888 ports वापरात असल्यास हा target सुरू होत नाही. मालक शोधण्यासाठी lsof -iTCP:3000 -sTCP:LISTEN वापरा.

FAQ

graph memory सह mem0 चालवण्यासाठी मला अजूनही Neo4j आवश्यक आहे का?

नाही. April 2026 मध्ये रिलीज झालेल्या नवीन memory algorithm ने open source SDK मधून graph_store आणि enable_graph configuration keys काढून टाकल्या. आता entity extraction सामान्य add प्रक्रियेदरम्यान चालते आणि <collection_name>_entities नावाच्या दुसऱ्या pgvector collection मध्ये लिहिली जाते. त्यामुळे external graph database, अतिरिक्त container किंवा migration step आवश्यक नाही. मात्र relations field search results मध्ये यापुढे उपलब्ध नाही. आता entities memory चे ranking वाढवतात; त्यांच्यातून traverse करण्यासाठी edges मिळत नाहीत. त्यामुळे त्या relationships वरून चालणाऱ्या application ला mem0 च्या बाहेर स्वतःचा graph store वापरावा लागेल.

self-hosted mem0 server चालवण्यासाठी सर्वात लहान VPS कोणता आहे?

language model दुसरीकडे host केलेला असल्यास, API container, Postgres आणि dashboard साठी 2 GB RAM आणि सुमारे 4 GB free disk पुरेसा आहे. पहिल्या build वेळी संसाधनांची सर्वाधिक गरज असते. कारण Next.js dashboard compile करण्यासाठी ते चालवण्यापेक्षा जास्त memory लागते. 1 GB च्या मशीनवर build process exit code 137 सह बंद होतो. Ollama त्याच server वर चालवत असल्यास, model नुसार sizing करा. 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 libraries समाविष्ट आहेत आणि HTTP 400 परत केला जातो. त्याऐवजी "provider": "openai" तसेच ठेवा आणि llm व embedder दोन्हीसाठी कोणतीही non empty api_key असलेली "openai_base_url": "http://ollama:11434/v1" सेट करा. Ollama key कडे दुर्लक्ष करते. Provider प्रत्यक्षात openai असल्यामुळे bundled provider check यशस्वी होते.

local embedding model वर स्विच केल्यानंतर mem0 कोणतेही results का परत करत नाही?

कारण pgvector table fixed 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 वर परिणाम होत नाही. embedding_model_dims मध्ये तुमच्या model ची वास्तविक width सेट करा. /v1/embeddings कॉल करून आणि त्यातून मिळणाऱ्या values ची संख्या मोजून ती width पडताळा. त्याच वेळी vector store साठी नवीन collection_name द्या.