openclaw - 💡(How to fix) Fix [Bug]: CLI subcommand dispatch remains 60-180s on modern laptop hardware after #5871 fixes

Official PRs (…)
ON THIS PAGE

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

After #5871 was closed with perf fixes merged, openclaw <subcommand> still takes 60–180 seconds on a Core i7-10850H laptop (NVMe, 16 GB RAM). Reproduces on 2026.4.15, a clean reinstall, and 2026.4.19-beta.2. Top-level openclaw --help and --version remain fast (~0.1–0.4s), but every subcommand — including pure help strings like openclaw cron --help — pays the full cost.

Bisecting the config against OPENCLAW_CONFIG_PATH shows an eager per-section init cost: removing any single top-level section alone produces zero measurable savings, but stripping many sections at once does. This suggests the startup penalty scales with the number of populated sections, not the contents of any one.

Root Cause

After #5871 was closed with perf fixes merged, openclaw <subcommand> still takes 60–180 seconds on a Core i7-10850H laptop (NVMe, 16 GB RAM). Reproduces on 2026.4.15, a clean reinstall, and 2026.4.19-beta.2. Top-level openclaw --help and --version remain fast (~0.1–0.4s), but every subcommand — including pure help strings like openclaw cron --help — pays the full cost.

Bisecting the config against OPENCLAW_CONFIG_PATH shows an eager per-section init cost: removing any single top-level section alone produces zero measurable savings, but stripping many sections at once does. This suggests the startup penalty scales with the number of populated sections, not the contents of any one.

Fix Action

Fix / Workaround

[Bug]: CLI subcommand dispatch remains 60–180s on modern laptop hardware after #5871 fixes

The openclaw.mjs entry point uses a light root-help.js loader for top-level --help / --version — that path is fast. Subcommands dispatch through dist/entry.js, which appears to eagerly import the union of all subcommand module graphs and scale validation per populated config section. Lazy import / per-subcommand module chunks would eliminate most of this cost for help text and simple queries.

Code Example

# Baseline (real config):
$ time openclaw cron --help > /dev/null
real  1m5.8s  user  1m36.9s  sys  3.2s

# Same binary, empty dev profile:
$ time openclaw --dev cron --help > /dev/null
real  3.3s    user  3.9s     sys  0.6s

---

OPENCLAW_STATE_DIR=/tmp/octest OPENCLAW_CONFIG_PATH=/tmp/octest/openclaw.json openclaw cron --help

---

/proc/<pid>/status: State: R (running)
wchan (main thread): 0   # actively executing
RAW_BUFFERClick to expand / collapse

[Bug]: CLI subcommand dispatch remains 60–180s on modern laptop hardware after #5871 fixes

Summary

After #5871 was closed with perf fixes merged, openclaw <subcommand> still takes 60–180 seconds on a Core i7-10850H laptop (NVMe, 16 GB RAM). Reproduces on 2026.4.15, a clean reinstall, and 2026.4.19-beta.2. Top-level openclaw --help and --version remain fast (~0.1–0.4s), but every subcommand — including pure help strings like openclaw cron --help — pays the full cost.

Bisecting the config against OPENCLAW_CONFIG_PATH shows an eager per-section init cost: removing any single top-level section alone produces zero measurable savings, but stripping many sections at once does. This suggests the startup penalty scales with the number of populated sections, not the contents of any one.

Environment

  • Distro: Ubuntu 24.04 (Linux 6.17.0-20-generic x86_64)
  • CPU: Intel i7-10850H (6c/12t @ 2.70 GHz)
  • RAM: 16 GB
  • Disk: NVMe (ext4)
  • Node: v24.14.0 (via nvm)
  • OpenClaw: 2026.4.15 and 2026.4.19-beta.2 (both reproduce)
  • Install: npm install -g openclaw@<version>
  • Config: ~7 KB openclaw.json, 9 Telegram accounts, ~45 crons, 8 isolated agents (main, camila, charlie, frank, gaston, jefferson, robert, seth, tobias)

Reproduction

# Baseline (real config):
$ time openclaw cron --help > /dev/null
real  1m5.8s  user  1m36.9s  sys  3.2s

# Same binary, empty dev profile:
$ time openclaw --dev cron --help > /dev/null
real  3.3s    user  3.9s     sys  0.6s

Bisect — individual section removal does not help

All runs against a fresh, empty state dir with only openclaw.json present, via:

OPENCLAW_STATE_DIR=/tmp/octest OPENCLAW_CONFIG_PATH=/tmp/octest/openclaw.json openclaw cron --help
Config variantcron --help wall time
Full config (baseline)65.8 s
No channels (drops 9 Telegram accounts)67.0 s
No agents block66.9 s
No bindings65.9 s
No models62.4 s
Strip channels,agents,bindings,models,skills,plugins,hooks,browser,commands,wizard,tools (keep only gateway/auth/meta/messages)20.2 s
Empty --dev profile (no config file at all)3.3 s

Interpretation:

  • Individual section removal: ≤4s saved. Within noise.
  • Aggregate stripping: 45s saved.
  • A ~17s residual gap between minimal-config and no-config remains.

Ruled out

  • Compile cache. NODE_COMPILE_CACHE=~/.cache/node-compile-cache populates to 6.6 MB / 1139 files after a successful warm run. Second run time unchanged.
  • Respawn overhead. OPENCLAW_NO_RESPAWN=1 — no measurable change.
  • Install corruption. npm uninstall -g openclaw && npm install -g [email protected] — no change.
  • Beta fix candidate. 2026.4.19-beta.2 reproduces identically.
  • Node version. 2026.2.13 install under Node 22.22.0 reproduces identically (different openclaw version, same symptom).
  • State-dir content. Empty OPENCLAW_STATE_DIR gives the same baseline time as the real state dir (contains 2 GB+ of workspaces + logs + cron history).
  • Memory SQLite files. Copying 59 MB of .openclaw/memory/*.sqlite (7 files, up to 13 MB each) into the test state dir changes stripped-config time from 21.1s → 21.7s (noise).

CPU profile signal

CPU time is ~1.5× wall clock (e.g. 96s CPU over 65s wall) — heavy compute, not network/IO wait. Thread state during the hang:

/proc/<pid>/status: State: R (running)
wchan (main thread): 0   # actively executing

NODE_DEBUG=module shows continuous module loading well past 15 seconds (>7100 log lines at t=15s, still growing). Modules loaded are all under openclaw/dist/* — 72 MB / 2279 chunks — not user config or plugin code.

Why this matters beyond --help

Any workflow that shells out to openclaw <subcommand> pays this cost per invocation. A Python cron that does 7 subprocess.run(["openclaw", "browser", ...]) calls pays ~7–20 minutes of pure CLI startup overhead before any browser work happens. For scripted/automation contexts this is a hard blocker; the WebSocket gateway itself (used by the webchat UI) responds to the same underlying RPCs in ~100 ms.

Suggested direction

The openclaw.mjs entry point uses a light root-help.js loader for top-level --help / --version — that path is fast. Subcommands dispatch through dist/entry.js, which appears to eagerly import the union of all subcommand module graphs and scale validation per populated config section. Lazy import / per-subcommand module chunks would eliminate most of this cost for help text and simple queries.

Relation to #5871

#5871 was closed 2026-03-02 after perf improvements were merged. This report demonstrates a distinct, still-present eager-init cost that scales with config-section count, on a machine significantly more powerful than the Pi4B reported in the original issue. Happy to re-bisect against any specific commits or flags if helpful.

extent analysis

TL;DR

The likely fix involves implementing lazy loading of subcommand modules and validation to reduce the eager initialization cost that scales with the number of populated config sections.

Guidance

  1. Investigate lazy import: Modify the dist/entry.js file to use lazy imports for subcommand modules, loading them only when the specific subcommand is invoked.
  2. Optimize validation: Review the validation process for config sections and consider optimizing or deferring it to reduce the startup time.
  3. Profile and benchmark: Use tools like NODE_DEBUG=module and CPU profiling to identify performance bottlenecks and measure the impact of changes.
  4. Consider chunking: Split the large openclaw/dist/* module into smaller chunks to reduce the overhead of loading and processing.
  5. Review config parsing: Examine how the config file is parsed and consider optimizations, such as parsing only the necessary sections for each subcommand.

Example

// dist/entry.js (simplified example)
const subcommands = {
  // ...
};

// Lazy import subcommand modules
Object.keys(subcommands).forEach((subcommand) => {
  subcommands[subcommand] = () => import(`./subcommands/${subcommand}`);
});

Notes

The provided information suggests that the issue is related to the eager initialization of subcommand modules and validation. However, without access to the full codebase, it's challenging to provide a definitive solution. The suggested direction involves implementing lazy loading and optimizing validation, but further investigation and profiling are necessary to determine the most effective approach.

Recommendation

Apply a workaround by implementing lazy loading of subcommand modules and optimizing validation, as this approach addresses the identified performance bottleneck and has the potential to significantly reduce the startup time.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING