Builtin Memory Engine: SQLite Backend for Agent Memory

Learn about the default SQLite-based memory backend with keyword, vector, and hybrid search. This page covers setup, features, and optional acceleration for developers using Neura Market.

Read this when

  • You want to understand the default memory backend
  • You want to configure embedding providers or hybrid search
  • You are migrating from the removed QMD memory backend

The builtin engine serves as the default memory backend. Your memory index lives in a per-agent SQLite database, and no additional dependencies are required to begin using it.

What it provides

  • Keyword search powered by FTS5 full-text indexing (BM25 scoring).
  • Vector search using embeddings from any supported provider.
  • Hybrid search merging both approaches for optimal results.
  • Deterministic ranking based on relevance, recency, and write-time importance.
  • Diversity-aware ordering with MMR applied to hybrid results by default.
  • Trusted trigger recall delivering bounded pre-reply context without needing a recall model.
  • CJK support through trigram tokenization for Chinese, Japanese, and Korean.
  • sqlite-vec acceleration enabling in-database vector queries (optional).

Getting started

OpenAI embeddings are the default for the builtin engine. When OPENAI_API_KEY or models.providers.openai.apiKey is already set up, vector search functions without any further memory configuration.

To specify a provider explicitly:

{
  memory: {
    search: {
      provider: "openai",
    },
  },
}

Without an embedding provider configured, only keyword search remains available.

To enable local GGUF embeddings, install and configure the official llama.cpp provider, then direct local.modelPath to a GGUF file:

openclaw plugins install @openclaw/llama-cpp-provider
{
  memory: {
    search: {
      provider: "local",
      fallback: "none",
      local: {
        modelPath: "~/.openclaw/models/llama.cpp/hf_ggml-org_embeddinggemma-300m-qat-Q8_0.gguf",
      },
    },
  },
}

Supported embedding providers

ProviderIDNotes
BedrockbedrockUses the AWS credential chain
DeepInfradeepinfraDefault: BAAI/bge-m3
GeminigeminiSupports multimodal (image + audio)
GitHub Copilotgithub-copilotUses your Copilot subscription
LM StudiolmstudioLocal/self-hosted
LocallocalOpenClaw-managed llama.cpp server
Mistralmistral
OllamaollamaLocal/self-hosted
OpenAIopenaiDefault: text-embedding-3-small
OpenAI-compatibleopenai-compatibleGeneric /v1/embeddings endpoint
Voyagevoyage

To move away from OpenAI, configure memory.search.provider.

How indexing works

OpenClaw processes MEMORY.md, an existing root USER.md, and memory/*.md into chunks (400 tokens with 80-token overlap by default) and persists them in a per-agent SQLite database. Automatic creation of USER.md does not happen.

Each chunk may hold nullable importance and trigger metadata. Null values act neutrally, keeping older indexes functional. Search blends hybrid relevance, recency decay, and importance before MMR diversity is applied; trigger recall injects only curated or promoted-trusted entries.

SQLite-owned provenance accompanies every indexed chunk: origin class (owner, agent, untrusted, or system), session kind, observation time, and an optional supersession key. This metadata lives separately from Markdown, so recalled prose cannot overwrite its own trust classification.

  • Index location: the owning agent database at ~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite
  • Storage maintenance: SQLite WAL sidecars stay bounded through periodic and shutdown checkpoints.
  • File watching: memory file changes trigger a debounced reindex (1.5s default).
  • Auto-reindex: the index rebuilds automatically when the embedding provider, model, chunking config, configured sources, or scope change.
  • Reindex on demand: openclaw memory index --force

Info

Markdown files outside the workspace can also be indexed with memory.search.extraPaths. See the configuration reference.

Migrating from QMD

QMD is gone; builtin stands as the sole memory engine. After upgrading, execute:

openclaw doctor --fix

Doctor clears the retired memory.backend, memory.qmd, and memory.search.qmd settings, including agent-scoped memory.search.qmd forms. QMD paths and extra collections are preserved as the matching memory.search.extraPaths entries, including { path, pattern } globs. When Memory Core locates 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 stays in MEMORY.md, USER.md, memory/*.md, and the migrated extra paths. Builtin indexes those same Markdown sources during its next sync. The cutover loses nothing by design: canonical memory content is neither copied nor deleted; only derived state gets rebuilt.

Builtin now addresses most QMD use cases through:

  • 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 in memory.search.extraPaths, and
  • optional image and audio indexing under extraPaths only.

Learned cross-encoder reranking and HyDE generation from QMD query mode do not exist in builtin memory. MMR trims duplicate results but does not act as a learned relevance reranker. To stand in for QMD's in-process, zero-key GGUF embeddings, install the llama.cpp provider and set memory.search.provider: "local"; without an embedding provider, builtin falls back to BM25 keyword search only.

When to use

For most users, the builtin engine is the appropriate pick:

  • Operates immediately with no extra dependencies.
  • Handles keyword and vector search effectively.
  • Works with every embedding provider.
  • Hybrid search draws on the strengths of both retrieval methods.

Directories outside the workspace can be indexed by the builtin engine using memory.search.extraPaths. Bounded lexical query expansion boosts conversational recall, but no learned or model-based relevance reranking stage is provided. Its MMR pass runs deterministically and locally.

If you need cross-session memory with automatic user modeling, look at Honcho.

Troubleshooting

Memory search disabled? Inspect openclaw memory status. When no provider is detected, set one explicitly or supply an API key.

Local provider not detected? Run interactive llama.cpp setup once, verify the local path exists, and execute:

openclaw memory status --deep --agent main
openclaw memory index --force --agent main

Both standalone CLI commands and the Gateway rely on the same local provider id.
For local embeddings, set memory.search.provider: "local".

Getting stale results? Rebuild with openclaw memory index --force. In rare edge cases, the watcher can overlook changes.

sqlite-vec failing to load? OpenClaw automatically switches to in-process cosine similarity. openclaw memory status --deep distinguishes the local vector store from the embedding provider, so Vector store: unavailable indicates sqlite-vec loading issues, while Embeddings: unavailable points to provider/auth or model readiness. Inspect the logs for the exact load error.

Configuration

For details on embedding provider setup, search result limits and thresholds, batch indexing, multimodal memory, sqlite-vec, extra paths, and other configuration options, refer to the Memory configuration reference.

1,031 words · updated Aug 16, 2026