What it provides
- Keyword search via FTS5 full-text indexing (BM25 scoring).
- Vector search via embeddings from any supported provider.
- Hybrid search that combines both for best results.
- Deterministic ranking by relevance, recency, and write-time importance.
- Diversity-aware ordering with MMR enabled on hybrid results by default.
- Trusted trigger recall for bounded pre-reply context without a recall model.
- CJK support via trigram tokenization for Chinese, Japanese, and Korean.
- sqlite-vec acceleration for in-database vector queries (optional).
Getting started
By default, the builtin engine uses OpenAI embeddings. IfOPENAI_API_KEY or
models.providers.openai.apiKey is already configured, vector search works
with no extra memory config.
To set a provider explicitly:
local.modelPath at a GGUF file:
Supported embedding providers
Set
memory.search.provider to switch away from OpenAI.
How indexing works
OpenClaw indexesMEMORY.md, an existing root USER.md, and memory/*.md into
chunks (400 tokens with 80-token overlap by default) and stores them in a
per-agent SQLite database. OpenClaw does not create USER.md automatically.
Each chunk can carry nullable importance and trigger metadata. Null values are
neutral, so older indexes remain usable. Search combines hybrid relevance,
recency decay, and importance before applying MMR diversity; trigger recall
only injects curated or promoted-trusted entries.
Each indexed chunk also has SQLite-owned provenance: origin class (owner,
agent, untrusted, or system), session kind, observation time, and an
optional supersession key. This metadata is stored separately from Markdown
so recalled prose cannot rewrite its own trust classification. Automatic
session ingestion also records source-session origins for its staged entries,
which support selective deletion after promotion. For coverage and limits, see
Memory provenance and deletion.
- Index location: the owning agent database at
~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite - Storage maintenance: SQLite WAL sidecars are bounded with periodic and shutdown checkpoints.
- File watching: changes to memory files trigger a debounced reindex (1.5s default).
- Index compatibility: changing the embedding provider, model, settings, configured sources, or scope can pause search until you explicitly rebuild. See provider selection.
- Reindex on demand:
openclaw memory index --force --agent <id>
openclaw memory status reports stored chunk text and JSON embedding bytes
for each source (sourceCounts[].chunkBytes in JSON). These are payload sizes,
not total disk usage: embedding cache, FTS/vector tables, SQLite overhead, and
WAL/free pages are excluded.
After an upgrade, automatic project and trigger recall may need to repair
legacy provenance. That repair runs in the background. Replies continue while
automatic recall stays empty until the affected sources have been reclassified.
You can also index Markdown files outside the workspace with
memory.search.extraPaths. See the
configuration reference.Migrating from QMD
QMD has been removed; builtin is the only memory engine. After upgrading, run:memory.backend, memory.qmd, and
memory.search.qmd settings, including agent-scoped memory.search.qmd
forms. It preserves QMD paths and extra collections as the corresponding
memory.search.extraPaths entries, including { path, pattern } globs. When
QMD session indexing was enabled, Doctor also enables builtin session indexing
and adds sessions to memory.search.sources without enabling broader
cross-conversation recall. Retained session-reset transcripts remain in the
agent’s sessions directory and are indexed from those original artifacts.
When Memory Core finds a retired per-agent QMD workspace under
~/.openclaw/agents/<agentId>/qmd/, Doctor also offers to remove its derived
indexes, model downloads, collection metadata, and session exports.
Canonical memory remains in MEMORY.md, USER.md, memory/*.md, and the
migrated extra paths. Builtin indexes those same Markdown sources on its next
sync. The cutover is lossless by construction: no canonical memory content is
copied or deleted; only derived state is rebuilt.
Builtin now covers most QMD use cases with:
- hybrid BM25 and vector retrieval by default, followed by temporal decay, importance, and project affinity before MMR diversity,
- bounded lexical query expansion for conversational searches,
- string or
{ path, pattern }entries inmemory.search.extraPaths, and - optional image and audio indexing under
extraPathsonly.
memory.search.provider: "local"; without an embedding provider, builtin uses
BM25 keyword search only.
When to use
The builtin engine is the right choice for most users:- Works out of the box with no extra dependencies.
- Handles keyword and vector search well.
- Supports all embedding providers.
- Hybrid search combines the best of both retrieval approaches.
memory.search.extraPaths. It uses bounded lexical query expansion to improve
conversational recall, but it does not provide a learned or model-based relevance
reranking stage. Its MMR pass is deterministic and local.
Consider Honcho if you want cross-session memory
with automatic user modeling.
Troubleshooting
Memory search disabled? Checkopenclaw memory status. If no provider is
detected, set one explicitly or add an API key.
Local provider not detected? Run interactive llama.cpp setup once, confirm
the local path exists, and run:
local provider id.
Set memory.search.provider: "local" when you want local embeddings.
Stale results? Run openclaw memory index --force to rebuild. The watcher
may miss changes in rare edge cases.
sqlite-vec not loading? OpenClaw falls back to in-process cosine
similarity automatically. openclaw memory status --deep reports the local
vector store separately from the embedding provider, so Vector store: unavailable points at sqlite-vec loading while Embeddings: unavailable
points at provider/auth or model readiness. Check logs for the specific load
error.
Safe index recovery
To rebuild after stale results or an embedding-provider change, select the affected agent explicitly:memory reset:
--yes for non-interactive use. It clears only
memory-owned derived tables, preserving non-memory database tables, including
sessions and transcripts, and memory source files. It coordinates with
existing memory maintenance without restarting the Gateway, which can reindex
retained sources afterward. If indexing is busy, let it finish and retry reset.
Reset does not shrink the database file or recover already deleted data.
If indexing fails or the database grows unexpectedly, keep the database and
its sidecars, retain the verbose error, and create and verify a backup
before manual recovery. A large database alone does not show which tables are
responsible. Reindexing is not a session-history restore: if history is missing
after moving or deleting the database, recover from a verified backup using
the restore workflow.
Reclaim disk space
Start withopenclaw memory status --agent <agent-id> --json. Compare the
database and WAL sizes, reusable bytes, retained embedding-cache payload, and
per-source chunk payloads. Reusable bytes are pages already free inside SQLite;
they are not additional data. Cache and chunk payloads exclude indexes and
SQLite overhead, so they do not explain every byte in the shared file.
If the derived index needs to be discarded, create and verify a
backup, then stop the Gateway through its deployment owner and
stop other writers. Keep them stopped through reset and compaction so background
indexing cannot refill the cache between commands: