Skip to main content

Memory configuration reference

This page lists every configuration knob for OpenClaw memory search. For conceptual overviews, see: All memory search settings live under agents.defaults.memorySearch in openclaw.json unless noted otherwise.

Provider selection

KeyTypeDefaultDescription
providerstringauto-detectedEmbedding adapter ID: openai, gemini, voyage, mistral, ollama, local
modelstringprovider defaultEmbedding model name
fallbackstring"none"Fallback adapter ID when the primary fails
enabledbooleantrueEnable or disable memory search

Auto-detection order

When provider is not set, OpenClaw selects the first available:
  1. local — if memorySearch.local.modelPath is configured and the file exists.
  2. openai — if an OpenAI key can be resolved.
  3. gemini — if a Gemini key can be resolved.
  4. voyage — if a Voyage key can be resolved.
  5. mistral — if a Mistral key can be resolved.
ollama is supported but not auto-detected (set it explicitly).

API key resolution

Remote embeddings require an API key. OpenClaw resolves from: auth profiles, models.providers.*.apiKey, or environment variables.
ProviderEnv varConfig key
OpenAIOPENAI_API_KEYmodels.providers.openai.apiKey
GeminiGEMINI_API_KEYmodels.providers.google.apiKey
VoyageVOYAGE_API_KEYmodels.providers.voyage.apiKey
MistralMISTRAL_API_KEYmodels.providers.mistral.apiKey
OllamaOLLAMA_API_KEY (placeholder)
Codex OAuth covers chat/completions only and does not satisfy embedding requests.

Remote endpoint config

For custom OpenAI-compatible endpoints or overriding provider defaults:
KeyTypeDescription
remote.baseUrlstringCustom API base URL
remote.apiKeystringOverride API key
remote.headersobjectExtra HTTP headers (merged with provider defaults)
{
  agents: {
    defaults: {
      memorySearch: {
        provider: "openai",
        model: "text-embedding-3-small",
        remote: {
          baseUrl: "https://api.example.com/v1/",
          apiKey: "YOUR_KEY",
        },
      },
    },
  },
}

Gemini-specific config

KeyTypeDefaultDescription
modelstringgemini-embedding-001Also supports gemini-embedding-2-preview
outputDimensionalitynumber3072For Embedding 2: 768, 1536, or 3072
Changing model or outputDimensionality triggers an automatic full reindex.

Local embedding config

KeyTypeDefaultDescription
local.modelPathstringauto-downloadedPath to GGUF model file
local.modelCacheDirstringnode-llama-cpp defaultCache dir for downloaded models
Default model: embeddinggemma-300m-qat-Q8_0.gguf (~0.6 GB, auto-downloaded). Requires native build: pnpm approve-builds then pnpm rebuild node-llama-cpp.

Hybrid search config

All under memorySearch.query.hybrid:
KeyTypeDefaultDescription
enabledbooleantrueEnable hybrid BM25 + vector search
vectorWeightnumber0.7Weight for vector scores (0-1)
textWeightnumber0.3Weight for BM25 scores (0-1)
candidateMultipliernumber4Candidate pool size multiplier

MMR (diversity)

KeyTypeDefaultDescription
mmr.enabledbooleanfalseEnable MMR re-ranking
mmr.lambdanumber0.70 = max diversity, 1 = max relevance

Temporal decay (recency)

KeyTypeDefaultDescription
temporalDecay.enabledbooleanfalseEnable recency boost
temporalDecay.halfLifeDaysnumber30Score halves every N days
Evergreen files (MEMORY.md, non-dated files in memory/) are never decayed.

Full example

{
  agents: {
    defaults: {
      memorySearch: {
        query: {
          hybrid: {
            vectorWeight: 0.7,
            textWeight: 0.3,
            mmr: { enabled: true, lambda: 0.7 },
            temporalDecay: { enabled: true, halfLifeDays: 30 },
          },
        },
      },
    },
  },
}

Additional memory paths

KeyTypeDescription
extraPathsstring[]Additional directories or files to index
{
  agents: {
    defaults: {
      memorySearch: {
        extraPaths: ["../team-docs", "/srv/shared-notes"],
      },
    },
  },
}
Paths can be absolute or workspace-relative. Directories are scanned recursively for .md files. Symlink handling depends on the active backend: the builtin engine ignores symlinks, while QMD follows the underlying QMD scanner behavior. For agent-scoped cross-agent transcript search, use agents.list[].memorySearch.qmd.extraCollections instead of memory.qmd.paths. Those extra collections follow the same { path, name, pattern? } shape, but they are merged per agent and can preserve explicit shared names when the path points outside the current workspace. If the same resolved path appears in both memory.qmd.paths and memorySearch.qmd.extraCollections, QMD keeps the first entry and skips the duplicate.

Multimodal memory (Gemini)

Index images and audio alongside Markdown using Gemini Embedding 2:
KeyTypeDefaultDescription
multimodal.enabledbooleanfalseEnable multimodal indexing
multimodal.modalitiesstring[]["image"], ["audio"], or ["all"]
multimodal.maxFileBytesnumber10000000Max file size for indexing
Only applies to files in extraPaths. Default memory roots stay Markdown-only. Requires gemini-embedding-2-preview. fallback must be "none". Supported formats: .jpg, .jpeg, .png, .webp, .gif, .heic, .heif (images); .mp3, .wav, .ogg, .opus, .m4a, .aac, .flac (audio).

Embedding cache

KeyTypeDefaultDescription
cache.enabledbooleanfalseCache chunk embeddings in SQLite
cache.maxEntriesnumber50000Max cached embeddings
Prevents re-embedding unchanged text during reindex or transcript updates.

Batch indexing

KeyTypeDefaultDescription
remote.batch.enabledbooleanfalseEnable batch embedding API
remote.batch.concurrencynumber2Parallel batch jobs
remote.batch.waitbooleantrueWait for batch completion
remote.batch.pollIntervalMsnumberPoll interval
remote.batch.timeoutMinutesnumberBatch timeout
Available for openai, gemini, and voyage. OpenAI batch is typically fastest and cheapest for large backfills.

Session memory search (experimental)

Index session transcripts and surface them via memory_search:
KeyTypeDefaultDescription
experimental.sessionMemorybooleanfalseEnable session indexing
sourcesstring[]["memory"]Add "sessions" to include transcripts
sync.sessions.deltaBytesnumber100000Byte threshold for reindex
sync.sessions.deltaMessagesnumber50Message threshold for reindex
Session indexing is opt-in and runs asynchronously. Results can be slightly stale. Session logs live on disk, so treat filesystem access as the trust boundary.

SQLite vector acceleration (sqlite-vec)

KeyTypeDefaultDescription
store.vector.enabledbooleantrueUse sqlite-vec for vector queries
store.vector.extensionPathstringbundledOverride sqlite-vec path
When sqlite-vec is unavailable, OpenClaw falls back to in-process cosine similarity automatically.

Index storage

KeyTypeDefaultDescription
store.pathstring~/.openclaw/memory/{agentId}.sqliteIndex location (supports {agentId} token)
store.fts.tokenizerstringunicode61FTS5 tokenizer (unicode61 or trigram)

QMD backend config

Set memory.backend = "qmd" to enable. All QMD settings live under memory.qmd:
KeyTypeDefaultDescription
commandstringqmdQMD executable path
searchModestringsearchSearch command: search, vsearch, query
includeDefaultMemorybooleantrueAuto-index MEMORY.md + memory/**/*.md
paths[]arrayExtra paths: { name, path, pattern? }
sessions.enabledbooleanfalseIndex session transcripts
sessions.retentionDaysnumberTranscript retention
sessions.exportDirstringExport directory

Update schedule

KeyTypeDefaultDescription
update.intervalstring5mRefresh interval
update.debounceMsnumber15000Debounce file changes
update.onBootbooleantrueRefresh on startup
update.waitForBootSyncbooleanfalseBlock startup until refresh completes
update.embedIntervalstringSeparate embed cadence
update.commandTimeoutMsnumberTimeout for QMD commands

Limits

KeyTypeDefaultDescription
limits.maxResultsnumber6Max search results
limits.maxSnippetCharsnumberClamp snippet length
limits.maxInjectedCharsnumberClamp total injected chars
limits.timeoutMsnumber4000Search timeout

Scope

Controls which sessions can receive QMD search results. Same schema as session.sendPolicy:
{
  memory: {
    qmd: {
      scope: {
        default: "deny",
        rules: [{ action: "allow", match: { chatType: "direct" } }],
      },
    },
  },
}
Default is DM-only. match.keyPrefix matches the normalized session key; match.rawKeyPrefix matches the raw key including agent:<id>:.

Citations

memory.citations applies to all backends:
ValueBehavior
auto (default)Include Source: <path#line> footer in snippets
onAlways include footer
offOmit footer (path still passed to agent internally)

Full QMD example

{
  memory: {
    backend: "qmd",
    citations: "auto",
    qmd: {
      includeDefaultMemory: true,
      update: { interval: "5m", debounceMs: 15000 },
      limits: { maxResults: 6, timeoutMs: 4000 },
      scope: {
        default: "deny",
        rules: [{ action: "allow", match: { chatType: "direct" } }],
      },
      paths: [{ name: "docs", path: "~/notes", pattern: "**/*.md" }],
    },
  },
}