Summary
On OpenClaw 2026.4.29, per-turn preparation is very slow. The largest repeated contributor appears to be the aggregated core-plugin-tools stage, taking approximately 29–34s per turn.
This also happens in isolated sessions, and an agentTurn configured with toolsAllow: [] does not reduce the core-plugin-tools time.
Environment
- OpenClaw version:
2026.4.29
- Runtime: local OpenClaw gateway / agent runtime
- Issue observed during normal assistant turns, isolated session probes, and cron
agentTurn probes
Symptom
Repeated startup/prep traces show:
core-plugin-tools: approximately 29–34s
- Total prep time: approximately
60–70s
- Responses take a long time before model output begins
- Gateway and related commands degrade under load:
cron status/list becomes slow or times out
memory status / memory status --deep times out
- Gateway event loop delay spikes under load
Timing evidence
Baseline
Recent normal-turn traces consistently showed:
core-plugin-tools: ~29–34s
model-resolution: ~21–25s
auth: ~10–13s
stream-setup: ~13–15s
system-prompt: ~10–13s
Related read-only checks showed system-wide latency symptoms:
openclaw status --deep: ~13–27s
cron status/list: around 5s to timeout
openclaw memory status: timeout at 15s
openclaw memory status --deep: timeout at 45s
Isolated session reproduction
A clean isolated session probe with:
returned successfully, but timing remained slow:
- startup:
~48.2s
- prep:
~70.8s
core-plugin-tools: ~33.8s
This suggests the issue is not primarily caused by a long-lived current session.
toolsAllow: [] reproduction
A temporary agentTurn probe was configured with:
{
"toolsAllow": [],
"sessionTarget": "isolated",
"delivery": {
"mode": "none"
},
"deleteAfterRun": true
}
The turn returned OK, but timing remained near baseline:
- startup:
~42.1s
- prep:
~62.4s
core-plugin-tools: ~29.3s
So toolsAllow: [] did not appear to avoid tool/plugin construction cost.
Code finding
From code inspection, toolsAllow appears to be applied only after tool construction.
The helper:
applyEmbeddedAttemptToolsAllow(tools, toolsAllow)
returns all tools when toolsAllow is falsy or an empty array:
if (!toolsAllow || toolsAllow.length === 0) return tools
Additionally, createOpenClawCodingTools(...) appears to run before this filtering is applied, meaning the full construction cost is already paid before allowlist filtering can remove anything.
The inspected construction path indicates that createOpenClawCodingTools(...) builds or resolves:
- base coding tools
- exec/process/apply_patch tools
- channel agent tools
- OpenClaw tools
- plugin tools
- policy pipeline / wrappers / hooks
- deferred tool descriptions
createOpenClawTools(...) also constructs/resolves tools such as:
- canvas
- nodes
- cron
- message
- gateway
- agents/sessions/subagents
- session_status
- web/media tools
- plugin tools
resolvePluginTools(...) appears to resolve plugin runtime/load context and registry, iterate registry tools, run tool factories, and then optionally apply allowlist filtering.
Because core-plugin-tools is exposed as an aggregated stage in the timing logs, I cannot confirm from the available logs whether the 29–34s are mostly spent in base tool construction, plugin registry/factories, channel tools, policy wrapping, deferred descriptions, or some combination of these.
A non-empty allowlist such as:
{
"toolsAllow": ["session_status"]
}
would likely still pay most or all of the same construction cost if filtering happens after createOpenClawCodingTools(...), although I have not separately benchmarked that exact case.
Hypothesis
OpenClaw currently pays the global tool/plugin construction cost for every turn, even when tools are later filtered.
Also, toolsAllow: [] currently appears to mean “no filtering / unrestricted”, rather than “zero tools”. If that semantics is intentional, there does not seem to be an obvious supported way to request an explicit no-tools agentTurn.
Impact
This has a large user-visible latency impact:
- total prep time is often
~60–70s
- responses are delayed significantly before streaming/model output begins
- Gateway responsiveness degrades under load
- operational commands such as cron and memory status become slow or time out
Suggested fixes / design options
Possible improvements:
-
Distinguish undefined from [], if changing this semantics is acceptable:
toolsAllow: undefined = current default behavior / unrestricted
toolsAllow: [] = explicitly no tools
-
If toolsAllow: [] is intended to mean no tools, short-circuit when it is explicitly defined and empty:
- avoid calling
createOpenClawCodingTools(...)
- return an empty tool list early
-
If toolsAllow: [] must keep its current behavior, add an explicit no-tools mode, for example:
or:
-
Ideally pass the allowlist into tool construction earlier:
- avoid constructing tools that will be filtered out
- especially avoid resolving plugin tools/factories unless needed
-
Consider lazy-loading plugin tools:
- defer plugin registry/tool factory work until the tool is actually enabled or requested
Compatibility risks
Changing the semantics of toolsAllow: [] may break users who currently rely on an empty array meaning “no restriction”.
If that behavior is intentional or needs to remain stable, a new explicit flag such as disableTools: true or toolsMode: "none" may be safer.
Minimal reproduction
- Run a normal turn and inspect startup/prep timing.
- Run an isolated session with a trivial prompt:
- Run an
agentTurn with:
{
"toolsAllow": [],
"sessionTarget": "isolated",
"delivery": {
"mode": "none"
},
"deleteAfterRun": true
}
- Compare
core-plugin-tools timing across the three runs.
Observed result:
core-plugin-tools remains around 29–34s.
Desired result / question:
- If
toolsAllow: [] is intended to mean “no tools”, it would be useful for it to avoid constructing tools.
- If
toolsAllow: [] is intentionally “unrestricted”, is there another supported explicit no-tools mode for agentTurn?
- More generally, can allowlist/no-tools intent be applied before expensive tool/plugin construction?
Questions
- Is it intentional that
toolsAllow: [] means “do not filter tools” rather than “zero tools”?
- Is there a supported way to launch an
agentTurn without constructing tools?
- Would a non-empty allowlist currently still construct all tools before filtering?
- Are there fixes or performance improvements for this area in versions newer than
2026.4.29?
Summary
On OpenClaw
2026.4.29, per-turn preparation is very slow. The largest repeated contributor appears to be the aggregatedcore-plugin-toolsstage, taking approximately29–34sper turn.This also happens in isolated sessions, and an
agentTurnconfigured withtoolsAllow: []does not reduce thecore-plugin-toolstime.Environment
2026.4.29agentTurnprobesSymptom
Repeated startup/prep traces show:
core-plugin-tools: approximately29–34s60–70scronstatus/list becomes slow or times outmemory status/memory status --deeptimes outTiming evidence
Baseline
Recent normal-turn traces consistently showed:
core-plugin-tools:~29–34smodel-resolution:~21–25sauth:~10–13sstream-setup:~13–15ssystem-prompt:~10–13sRelated read-only checks showed system-wide latency symptoms:
openclaw status --deep:~13–27scron status/list: around5sto timeoutopenclaw memory status: timeout at15sopenclaw memory status --deep: timeout at45sIsolated session reproduction
A clean isolated session probe with:
returned successfully, but timing remained slow:
~48.2s~70.8score-plugin-tools:~33.8sThis suggests the issue is not primarily caused by a long-lived current session.
toolsAllow: []reproductionA temporary
agentTurnprobe was configured with:{ "toolsAllow": [], "sessionTarget": "isolated", "delivery": { "mode": "none" }, "deleteAfterRun": true }The turn returned
OK, but timing remained near baseline:~42.1s~62.4score-plugin-tools:~29.3sSo
toolsAllow: []did not appear to avoid tool/plugin construction cost.Code finding
From code inspection,
toolsAllowappears to be applied only after tool construction.The helper:
returns all tools when
toolsAllowis falsy or an empty array:Additionally,
createOpenClawCodingTools(...)appears to run before this filtering is applied, meaning the full construction cost is already paid before allowlist filtering can remove anything.The inspected construction path indicates that
createOpenClawCodingTools(...)builds or resolves:createOpenClawTools(...)also constructs/resolves tools such as:resolvePluginTools(...)appears to resolve plugin runtime/load context and registry, iterate registry tools, run tool factories, and then optionally apply allowlist filtering.Because
core-plugin-toolsis exposed as an aggregated stage in the timing logs, I cannot confirm from the available logs whether the29–34sare mostly spent in base tool construction, plugin registry/factories, channel tools, policy wrapping, deferred descriptions, or some combination of these.A non-empty allowlist such as:
{ "toolsAllow": ["session_status"] }would likely still pay most or all of the same construction cost if filtering happens after
createOpenClawCodingTools(...), although I have not separately benchmarked that exact case.Hypothesis
OpenClaw currently pays the global tool/plugin construction cost for every turn, even when tools are later filtered.
Also,
toolsAllow: []currently appears to mean “no filtering / unrestricted”, rather than “zero tools”. If that semantics is intentional, there does not seem to be an obvious supported way to request an explicit no-toolsagentTurn.Impact
This has a large user-visible latency impact:
~60–70sSuggested fixes / design options
Possible improvements:
Distinguish
undefinedfrom[], if changing this semantics is acceptable:toolsAllow: undefined= current default behavior / unrestrictedtoolsAllow: []= explicitly no toolsIf
toolsAllow: []is intended to mean no tools, short-circuit when it is explicitly defined and empty:createOpenClawCodingTools(...)If
toolsAllow: []must keep its current behavior, add an explicit no-tools mode, for example:{ "disableTools": true }or:
{ "toolsMode": "none" }Ideally pass the allowlist into tool construction earlier:
Consider lazy-loading plugin tools:
Compatibility risks
Changing the semantics of
toolsAllow: []may break users who currently rely on an empty array meaning “no restriction”.If that behavior is intentional or needs to remain stable, a new explicit flag such as
disableTools: trueortoolsMode: "none"may be safer.Minimal reproduction
agentTurnwith:{ "toolsAllow": [], "sessionTarget": "isolated", "delivery": { "mode": "none" }, "deleteAfterRun": true }core-plugin-toolstiming across the three runs.Observed result:
core-plugin-toolsremains around29–34s.Desired result / question:
toolsAllow: []is intended to mean “no tools”, it would be useful for it to avoid constructing tools.toolsAllow: []is intentionally “unrestricted”, is there another supported explicit no-tools mode foragentTurn?Questions
toolsAllow: []means “do not filter tools” rather than “zero tools”?agentTurnwithout constructing tools?2026.4.29?