Memory Configuration Reference for OpenClaw Search
This reference documents every configuration option for OpenClaw memory search, including retrieval modes and multimodal indexing. It is essential for developers tuning memory settings in openclaw.json.
Read this when
- You want to configure memory search providers or embedding models
- You want to understand hybrid search, MMR, or temporal-decay defaults
- You want to enable multimodal memory indexing
- You need to exclude specific session sources from automatic dreaming ingestion
- You see a memory file-watching pressure warning
This page documents every configuration option for OpenClaw memory search. For conceptual material, refer to:
-
Memory overview, What memory does.
-
Builtin engine, The default SQLite backend.
-
Memory search, How the search pipeline works and how to tune it.
-
Active memory, The memory sub-agent used in interactive sessions.
Shared memory settings all sit under the top-level memory key in openclaw.json. Search defaults draw from memory.search; agent-specific overrides use agents.entries.*.memory.search.
Note
For the recommended personal-agent setup, go with
memory.search.rememberAcrossConversations. Advanced controls for Active Memory targeting, model, prompt, and latency are located underplugins.entries.active-memory.Both activation paths, transcript persistence, and safe rollout guidance are covered in Active Memory.
Remember across conversations
| Key | Type | Default | Description |
|---|---|---|---|
rememberAcrossConversations | boolean | On for personal installs; off with configured DM isolation | Pull in relevant context from this agent's other recognized private conversations. |
Set it per agent when only a trusted personal agent should get cross-conversation transcript recall:
{
agents: {
entries: {
personal: {
memory: {
search: {
rememberAcrossConversations: true,
},
},
},
},
},
}
The value obeys standard memory.search inheritance with an
agent-level override. If unset, it turns on by default only when global
session.dmScope is unset or "main" and no binding carries a session.dmScope
override. Any configured DM isolation forces it off. An explicit true or
false always takes precedence. Enabling it implies session transcript indexing and adds
sessions to the agent's resolved memory sources.
OpenClaw's built-in memory provider supports this protected path. Other memory providers can rely on their own recall hooks and advanced Active Memory tools, but this setting is skipped unless the current provider supports protected private transcript recall. openclaw doctor reports an unsupported provider or an explicit Active Memory toolsAllow list that omits memory_search.
The retrieval boundary is tighter than general session search:
- only the same agent's recognized private conversations qualify
- the conversation being answered is left out
- groups and channels are not eligible as sources or destinations
- unknown conversation kinds fail closed
- sandboxed recall cannot use the special cross-conversation authorization
This setting does not alter tools.sessions.visibility, session keys, transcript storage, delivery routing, or the permissions of sessions_list, sessions_history, and sessions_send. Active Memory performs a bounded read-only retrieval pass; unavailable or timed-out retrieval does not block the reply.
Provider selection
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Turn memory search on or off |
provider | string | "openai" | Embedding adapter ID such as bedrock, deepinfra, gemini, github-copilot, local, mistral, ollama, openai, openai-compatible, or voyage; may also be a configured models.providers.<id> whose api points at a memory embedding adapter or OpenAI-compatible model API |
model | string | provider default | Embedding model name |
fallback | string | "none" | Fallback adapter ID when the primary fails |
When provider is not set, OpenClaw uses OpenAI embeddings. Set provider explicitly to use Bedrock, DeepInfra, Gemini, GitHub Copilot, Mistral, Ollama, Voyage, a local GGUF model, or an OpenAI-compatible /v1/embeddings endpoint. Legacy configs that still say provider: "auto" resolve to openai.
Warning
Changing the embedding provider, model, provider settings, sources, scope, chunking, or tokenizer can make the existing SQLite vector index incompatible. OpenClaw pauses vector search and reports an index identity warning instead of automatically re-embedding everything. Rebuild when you are ready with
openclaw memory status --index --agent <id>oropenclaw memory index --force --agent <id>.
When provider is not defined, the older provider: "auto" exists, or
provider: "none" explicitly chooses FTS-only operation, memory recall can fall
back on lexical FTS ranking if embeddings are missing.
Explicit non-local providers fail closed. When memory.search.provider is assigned
to a specific remote-backed provider like Bedrock, DeepInfra, Gemini, GitHub
Copilot, LM Studio, Mistral, Ollama, OpenAI, Voyage, or a custom
OpenAI-compatible provider, and that provider cannot be reached during
runtime, memory_search gives back an unavailable result rather than quietly
switching to FTS-only recall. To resolve this, correct the provider or auth
settings, move to a provider that is reachable, or assign provider: "none"
when you want FTS-only recall on purpose.
Custom provider ids
memory.search.provider may reference a custom models.providers.<id> entry for memory-specific
provider adapters such as ollama, or for OpenAI-compatible model APIs like
openai-responses / openai-completions. OpenClaw keeps the custom provider id for endpoint,
auth, and model-prefix handling while resolving that provider's api
owner for the embedding adapter. This enables multi-GPU or multi-host
configurations to direct memory embeddings to a particular local endpoint:
{
models: {
providers: {
"ollama-5080": {
api: "ollama",
baseUrl: "http://gpu-box.local:11435",
apiKey: "ollama-local",
models: [{ id: "qwen3-embedding:0.6b", name: "Qwen3 Embedding 0.6B" }],
},
},
},
memory: {
search: {
provider: "ollama-5080",
model: "qwen3-embedding:0.6b",
},
},
}
API key resolution
An API key is required for remote embeddings. Bedrock relies on the AWS SDK default credential chain instead (instance roles, SSO, access keys, or a Bedrock API key).
| Provider | Env var | Config key |
|---|---|---|
| Bedrock | AWS credential chain, or AWS_BEARER_TOKEN_BEDROCK | No API key needed |
| DeepInfra | DEEPINFRA_API_KEY | models.providers.deepinfra.apiKey |
| Gemini | GEMINI_API_KEY | models.providers.google.apiKey |
| GitHub Copilot | COPILOT_GITHUB_TOKEN, GH_TOKEN, GITHUB_TOKEN | Auth profile via device login |
| Mistral | MISTRAL_API_KEY | models.providers.mistral.apiKey |
| Ollama | OLLAMA_API_KEY (placeholder) | -- |
| OpenAI | OPENAI_API_KEY | models.providers.openai.apiKey |
| Voyage | VOYAGE_API_KEY | models.providers.voyage.apiKey |
Note
Codex OAuth only covers chat/completions and does not fulfill embedding requests.
Remote endpoint config
For a generic OpenAI-compatible /v1/embeddings server that should not pick up
global OpenAI chat credentials, use provider: "openai-compatible".
-
remote.baseUrl(string), Custom API base URL. -
remote.apiKey(string), Override API key. -
remote.headers(object), Extra HTTP headers (merged with provider defaults).
{
memory: {
search: {
provider: "openai-compatible",
model: "text-embedding-3-small",
remote: {
baseUrl: "https://api.example.com/v1/",
apiKey: "YOUR_KEY",
},
},
},
}
Provider-specific config
Gemini
| Key | Type | Default | Description |
|---|---|---|---|
model | string | gemini-embedding-001 | Also supports gemini-embedding-2-preview |
outputDimensionality | number | 3072 | For Embedding 2: 768, 1536, or 3072 |
Warning
The index identity changes when you alter the model or
outputDimensionality. OpenClaw halts vector search until the memory index is explicitly rebuilt.
OpenAI-compatible input types
Provider-specific input_type request fields can be enabled for
OpenAI-compatible embedding endpoints. This helps when asymmetric embedding
models need distinct labels for query and document embeddings.
| Key | Type | Default | Description |
|---|---|---|---|
inputType | string | unset | Shared input_type for query and document embeddings |
queryInputType | string | unset | Query-time input_type; overrides inputType |
documentInputType | string | unset | Index/document input_type; overrides inputType |
{
memory: {
search: {
provider: "openai-compatible",
remote: {
baseUrl: "https://embeddings.example/v1",
apiKey: "${EMBEDDINGS_API_KEY}",
},
model: "asymmetric-embedder",
queryInputType: "query",
documentInputType: "passage",
},
},
}
Adjusting these parameters alters the embedding cache identity used for provider batch indexing. When the upstream model interprets the labels differently, a memory reindex should follow.
Bedrock
Bedrock embedding config
Bedrock relies on the AWS SDK default credential chain combined with an OpenClaw-verified bearer token, so no API keys are stored in config. If OpenClaw runs on EC2 with a Bedrock-enabled instance role, simply specify the provider and model:
{
memory: {
search: {
provider: "bedrock",
model: "amazon.titan-embed-text-v2:0",
},
},
}
| Key | Type | Default | Description |
|---|---|---|---|
model | string | amazon.titan-embed-text-v2:0 | Any Bedrock embedding model ID |
outputDimensionality | number | model default | For Titan V2: 256, 512, or 1024 |
Supported models (with family detection and dimension defaults):
| Model ID | Provider | Default Dims | Configurable Dims |
|---|---|---|---|
amazon.titan-embed-text-v2:0 | Amazon | 1024 | 256, 512, 1024 |
amazon.titan-embed-text-v1 | Amazon | 1536 | -- |
amazon.titan-embed-g1-text-02 | Amazon | 1536 | -- |
amazon.titan-embed-image-v1 | Amazon | 1024 | -- |
amazon.nova-2-multimodal-embeddings-v1:0 | Amazon | 1024 | 256, 384, 1024, 3072 |
cohere.embed-english-v3 | Cohere | 1024 | -- |
cohere.embed-multilingual-v3 | Cohere | 1024 | -- |
cohere.embed-v4:0 | Cohere | 1536 | 256, 384, 512, 768, 1024, 1536 |
twelvelabs.marengo-embed-3-0-v1:0 | TwelveLabs | 512 | -- |
twelvelabs.marengo-embed-2-7-v1:0 | TwelveLabs | 1024 | -- |
Variants carrying throughput suffixes (for instance, amazon.titan-embed-text-v1:2:8k) and inference profile IDs prefixed with a region (for instance, us.amazon.titan-embed-text-v2:0) adopt the configuration of the base model.
Region: resolution follows this sequence: the memory.search.remote.baseUrl override, the models.providers.amazon-bedrock.baseUrl config, AWS_REGION, AWS_DEFAULT_REGION, and finally a fallback of us-east-1.
Authentication: OpenClaw first looks for AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY or AWS_BEARER_TOKEN_BEDROCK, then falls back to the standard AWS SDK default credential provider chain:
- Environment variables (
AWS_ACCESS_KEY_ID+AWS_SECRET_ACCESS_KEY), unlessAWS_PROFILEis also set - SSO (only when SSO fields are configured)
- Shared credentials and config files (
fromIni, includesAWS_PROFILE) - Credential process (
credential_processin the AWS config file) - Web identity token credentials
- ECS or EC2 instance metadata credentials
IAM permissions: the IAM role or user requires:
{
"Effect": "Allow",
"Action": "bedrock:InvokeModel",
"Resource": "*"
}
For least-privilege, scope InvokeModel to the specific model:
arn:aws:bedrock:*::foundation-model/amazon.titan-embed-text-v2:0
Local (managed llama.cpp server)
| Key | Type | Default | Description |
|---|---|---|---|
local.modelPath | string | auto-downloaded | Path to GGUF model file |
Install the official llama.cpp provider, then pick llama.cpp once during
interactive setup. OpenClaw installs a pinned, verified llama-server and
writes its loopback localService configuration. Default model:
embeddinggemma-300m-qat-Q8_0.gguf (~0.3 GB, auto-downloaded).
Verify the same provider path the Gateway uses through the standalone CLI:
openclaw memory status --deep --agent main
openclaw memory index --force --agent main
Cache placement is owned by the provider. openclaw memory status --deep reports
server build, model path, capability, and endpoint facts observed from the
managed server after it has handled an embedding request.
Set provider: "local" explicitly for local GGUF embeddings. Full hf:
file references and integrity-bearing HTTPS GGUF URLs are supported for
explicit local configs, but they do not change the default provider.
Indexing behavior
Memory engines own synchronization, batching, watch, and post-compaction indexing heuristics. OpenClaw keeps these behaviors enabled with maintained defaults rather than exposing per-install timing switches.
Hybrid search config
All under memory.search.query:
| Key | Type | Default | Description |
|---|---|---|---|
maxResults | number | 6 | Max memory hits returned before injection |
minScore | number | 0.35 | Minimum relevance score to include a hit |
Hybrid retrieval remains enabled. The builtin engine always applies a fixed
30-day recency half-life to dated daily notes and a fixed importance
multiplier after hybrid relevance, then applies MMR diversity ordering with a
fixed lambda of 0.7. MEMORY.md, USER.md, and other evergreen memory files
do not decay. Nullable importance is neutral, so no migration or new tuning
key is required for existing indexes.
Strong matches on promoted or trusted entries can add up to three compact memories during eligible interactive turns. As of now, root MEMORY.md and USER.md make up the curated eligible tier. Daily notes and transcripts are never injected automatically.
Full example
{
memory: {
search: {
query: {
maxResults: 6,
minScore: 0.35,
},
},
},
}
Additional memory paths
| Key | Type | Description |
|---|---|---|
extraPaths | Array<string | { path: string; pattern?: string }> | Extra directories or files to include in indexing |
{
memory: {
search: {
extraPaths: ["../team-docs", { path: "/srv/shared-notes", pattern: "runbooks/**/*.md" }],
},
},
}
Paths may be absolute or relative to the workspace. Directories get scanned recursively for supported files. Object entries limit a directory using a root-relative glob with / separators; direct file entries get indexed exactly as given. The builtin engine does not follow symlinks.
Multimodal memory (Gemini)
Index images and audio next to Markdown via Gemini Embedding 2:
| Key | Type | Default | Description |
|---|---|---|---|
multimodal.enabled | boolean | false | Turn on multimodal indexing |
multimodal.modalities | string[] | -- | ["image"], ["audio"], or ["all"] |
multimodal.maxFileBytes | number | 10485760 | Largest file size accepted for indexing (10 MiB) |
Note
This only affects files under
extraPaths. Default memory roots continue to handle Markdown only.gemini-embedding-2-previewis a prerequisite.fallbackhas to be set to"none".
Recognized formats: .jpg, .jpeg, .png, .webp, .gif, .heic, .heif for images; .mp3, .wav, .ogg, .opus, .m4a, .aac, .flac for audio.
Embedding cache
| Key | Type | Default | Description |
|---|---|---|---|
cache.enabled | boolean | true | Store chunk embeddings in SQLite as a cache |
This avoids re-embedding unchanged text during reindex runs or transcript updates.
Batch indexing
| Key | Type | Default | Description |
|---|---|---|---|
remote.batch.enabled | boolean | false | Use the batch embedding API |
Supported for gemini, openai, and voyage. For large backfills, OpenAI batch usually delivers the best speed and cost.
Batch enablement stands as the sole remote batching control. Concurrency, polling, and timeout details belong to the provider.
Session memory search
Index session transcripts and expose them through memory_search:
| Key | Type | Default | Description |
|---|---|---|---|
rememberAcrossConversations | boolean | On for personal installs; off with configured DM isolation | Allow private recall across conversations |
sources | string[] | ["memory"] | Add "sessions" to bring in transcripts |
Warning
Session indexing is optional and runs in the background. Results may be slightly out of date. Session logs reside on disk, so treat filesystem access as the trust boundary.
Note
Conversation fragments are written to
<workspace>/memory/by the session-memory hook, and thememorysource already has those indexed. When transcript indexing runs as well, the same dialogue can surface through bothmemoryandsessions, which leads to duplicated search hits and extra embedding costs. To rely solely on the hook for recall, configuresources: ["memory"]andrememberAcrossConversations: false; settingsourcesby itself will not work, since cross-conversation recall always pulls insessions. If you prefer full-transcript recall, executeopenclaw hooks disable session-memory. Turn on both features only when you deliberately want the two representations side by side.
Standard session transcript search triggered by the model respects tools.sessions.visibility. By default, tree visibility covers the current session, any sessions it created, and same-agent group sessions seen through ambient group awareness. For other unrelated sessions, agent visibility is needed, or all only when cross-agent recall is also necessary and the agent-to-agent policy permits it.
rememberAcrossConversations does not broaden that visibility setting. It adds a separate runtime-only permission, scoped to same-agent private transcripts during the limited Active Memory pass.
The following examples put these settings at the top-level memory.search. Equivalent settings can also be applied through a per-agent memory.search override when just one agent should index and search session transcripts.
For recall between a gateway and DM within the same agent:
{
memory: {
search: {
experimental: { sessionMemory: true },
sources: ["memory", "sessions"],
},
},
tools: {
sessions: { visibility: "agent" },
},
}
SQLite vector acceleration (sqlite-vec)
| Key | Type | Default | Description |
|---|---|---|---|
store.vector.enabled | boolean | true | Use sqlite-vec for vector queries |
store.vector.extensionPath | string | bundled | Override sqlite-vec path |
If sqlite-vec is not present, OpenClaw automatically switches to in-process cosine similarity.
Index storage
Each agent's OpenClaw SQLite database holds the built-in memory indexes at agents/<agentId>/agent/openclaw-agent.sqlite.
| Key | Type | Default | Description |
|---|---|---|---|
store.fts.tokenizer | string | unicode61 | FTS5 tokenizer (unicode61 or trigram) |
Citations
Citation visibility for built-in memory results is governed by memory.citations:
| Value | Behavior |
|---|---|
auto (default) | Include Source: <path#line> when useful |
on | Always include the source footer |
off | Omit the footer; the path remains available internally |
Dreaming
Dreaming is set up under plugins.entries.memory-core.config.dreaming, not under memory.search.
A single scheduled sweep runs dreaming, with internal light/deep/REM phases treated as an implementation detail.
For conceptual behavior and slash commands, see Dreaming.
User settings
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable or disable dreaming entirely |
frequency | string | 0 3 * * * | Optional cron cadence for the full dreaming sweep |
model | string | default model | Optional Dream Diary subagent model override |
phases.deep.maxPromotedSnippetTokens | number | 160 | Maximum estimated tokens kept from each short-term recall snippet promoted into MEMORY.md; provenance metadata remains visible |
phases.deep.maxPriorEntryLossFraction | number | 0.25 | Reject a consolidation rewrite that removes more than this fraction of prior entries |
Example
{
plugins: {
entries: {
"memory-core": {
subagent: {
allowModelOverride: true,
allowedModels: ["anthropic/claude-sonnet-4-6"],
},
config: {
dreaming: {
enabled: true,
frequency: "0 3 * * *",
model: "anthropic/claude-sonnet-4-6",
},
},
},
},
},
}
Note
- Machine state gets written to
memory/.dreams/during dreaming.- Narrative output meant for humans is written to
DREAMS.md, or to the existingdreams.mdif that is present.- The prior
MEMORY.mdis stored in SQLite-backed plugin state by deep consolidation, which also logs rewrite counts and highlights intoDREAMS.md.- Candidates from untrusted or system-derived sources are filtered out structurally before consolidation and durable promotion take place.
- The existing plugin subagent trust gate is what
dreaming.modelrelies on; make sureplugins.entries.memory-core.subagent.allowModelOverride: trueis set before turning it on.- When the configured model is unavailable, Dream Diary makes one retry using the session default model. Failures tied to trust or allowlist checks are recorded in logs and are not retried silently.
- The light/deep/REM phase policy and its thresholds are internal behavior, not something users configure.