Operations — Background Jobs, Scripts, Cron, and Upgrades
Everything that runs automatically or needs periodic attention.
Automatic background jobs (no setup needed)
These run inside the gateway process. No cron, no external scheduler.
| Job | Interval | What it does | Log signature |
|---|---|---|---|
| Prune | Every 60 minutes | Hard-deletes expired facts; soft-decays confidence for facts past ~75% of TTL | memory-hybrid: periodic prune — N expired, M decayed |
| Auto-classify | Every 24 hours + once at startup (5 min delay) | Reclassifies “other” facts into proper categories via LLM. Only runs if autoClassify.enabled is true | memory-hybrid: auto-classify done — reclassified N/M facts |
| Proposal prune | Every 60 minutes | Removes expired persona proposals. Only runs if personaProposals.enabled is true | memory-hybrid: pruned N expired proposal(s) |
| WAL recovery | Once at startup | Replays uncommitted write-ahead log entries from a crash | memory-hybrid: WAL recovery completed — recovered N |
| Startup prune | Once at startup | Deletes any expired facts immediately | (included in periodic prune log) |
All timers are cleaned up on gateway stop. No orphaned processes.
Optional scheduled jobs (cron / OpenClaw jobs)
These are not required for core functionality but enhance the system for long-running setups.
How to enable when “not defined”:
- Recommended: Run
openclaw hybrid-mem verify --fix. This adds any missing maintenance jobs (9 canonical jobs) when they are missing (without overwriting existing jobs) to~/.openclaw/cron/jobs.json(and, if present, thejobsarray in~/.openclaw/openclaw.json). See CLI-REFERENCE.md § Maintenance cron jobs for the full table (nightly-memory-sweep, self-correction-analysis, nightly-dream-cycle, weekly-reflection, weekly-extract-procedures, weekly-deep-maintenance, weekly-persona-proposals, monthly-consolidation). - Or add the job definitions manually to
~/.openclaw/openclaw.json(under a top-leveljobsarray if your OpenClaw version uses it) or to~/.openclaw/cron/jobs.json(see snippets below). - Or run the standalone install script from the repo:
node scripts/install-hybrid-config.mjs(merges full defaults including jobs into openclaw.json).
After adding jobs, the gateway will pick them up on next start (or according to your host’s job reload behavior). No plugin restart needed for cron store changes in many setups.
For isolated hybrid-mem:* jobs, do not set sessionKey to agent:main:main (or any interactive session key). Leave sessionKey unset so OpenClaw resolves per-job isolated keys (cron:<jobId>). verify --fix strips bad top-level sessionKey values for isolated hybrid-mem jobs.
Nightly session distillation
Extracts durable facts from old conversation logs. Recommended if you want to capture knowledge from sessions where auto-capture missed things.
OpenClaw jobs (recommended): The openclaw hybrid-mem install command adds the nightly distillation and weekly reflection jobs to your config. When you run openclaw hybrid-mem verify --fix, missing jobs are added with a model chosen from your config (llm.default / llm.heavy when set, else legacy: Gemini → distill, Claude → claude, else OpenAI → reflection). See CONFIGURATION.md § LLM routing and model preference and LLM-AND-PROVIDERS.md.
Example structure (actual model value is filled from your provider at install/verify time):
{
"jobs": [
{
"name": "nightly-memory-sweep",
"schedule": "0 2 * * *",
"channel": "system",
"message": "Run nightly session distillation: last 3 days, isolated session.",
"isolated": true,
"model": "gemini-2.0-flash"
}
]
}
This runs at 2 AM daily as an isolated sub-agent. It processes session logs from the last 3 days (incremental), extracts facts, dedupes, and stores.
System cron alternative: If you prefer system cron over OpenClaw’s job scheduler:
# Add to crontab (crontab -e)
0 2 * * * cd ~/.openclaw && openclaw hybrid-mem distill >> /var/log/openclaw-distill.log 2>&1
Distill automatically records the run timestamp so the next job uses the correct incremental window and verify shows the last run.
Distillation window commands:
# See what the next distillation run would process
openclaw hybrid-mem distill-window
# Machine-readable output for scripts
openclaw hybrid-mem distill-window --json
# → {"mode":"incremental","startDate":"2026-02-14","endDate":"2026-02-17","mtimeDays":3}
See SESSION-DISTILLATION.md for the full pipeline details.
Weekly reflection
Synthesizes behavioral patterns from recent facts. The openclaw hybrid-mem install command adds a weekly job; verify --fix adds it when missing.
{
"name": "weekly-reflection",
"schedule": "0 3 * * 0",
"channel": "system",
"message": "Run memory reflection: analyze facts from the last 14 days, extract behavioral patterns, store as pattern-category facts. Use memory_reflect tool.",
"isolated": true,
"model": "gpt-4o-mini"
}
Runs at 3 AM Sundays. The model value is resolved from your config (see CONFIGURATION.md § Default model selection). Requires reflection.enabled: true in plugin config. See REFLECTION.md.
What the two jobs cover (and what they don’t)
| What | Covered by | Notes |
|---|---|---|
| Session distillation (facts from old conversation logs) | nightly-memory-sweep | Distill automatically records the run timestamp after completion. With distill.extractDirectives / distill.extractReinforcement the same run can extract directives and reinforcement. |
| Reflection (pattern synthesis from facts) | weekly-reflection | Uses memory_reflect; requires reflection.enabled: true. |
| Prune expired facts | Gateway (every 60 min) | No cron job needed. |
| Auto-classify (“other” → categories) | Gateway (every 24 h if enabled) | No cron job needed. |
| Compaction (tier migration hot/warm/cold) | Gateway (on session end if memoryTiering.compactionOnSessionEnd) | No cron job needed. |
| Procedural memory (extract procedures from sessions) | Not in the two jobs | Run openclaw hybrid-mem extract-procedures on a schedule (e.g. weekly after distill) if you want procedures updated from session logs. |
| Self-correction analysis | Optional third job | The repo’s scripts/install-hybrid-config.mjs adds a self-correction-analysis job; you can add it manually or run openclaw hybrid-mem self-correction-run on a schedule. |
So the two suggested jobs (nightly sweep + weekly reflection) cover distillation and reflection. Everything else that must run regularly (prune, auto-classify, compaction) runs inside the gateway. Only extract-procedures and self-correction are additional optional schedules if you want them.
Weekly extraction pipeline (procedures, directives, reinforcement)
The weekly-extract-procedures job (Sunday 04:00 by default) runs four steps in sequence: extract-procedures → extract-directives → extract-reinforcement → generate-auto-skills. Steps 1 and 2 are fast (no LLM); step 3 (extract-reinforcement) runs an LLM and can take several minutes; step 4 runs after step 3 completes.
Why “step 3 running in the background”? OpenClaw’s cron runner may send a status update after steps 1 and 2. At that moment step 3 is still running, so you see “extract-reinforcement: Currently running in the background” and “generate-auto-skills: Pending”. The plugin runs all four commands sequentially in one process; “background” here means step 3 is in progress. A single “all done” notification would require OpenClaw’s job runner to report only when the full chain exits.
- Job model: The job is scheduled with the nano tier, so the agent that runs these steps uses a cheap model (e.g. gpt-4.1-nano). Your primary model stays free for interactive use.
- extract-reinforcement LLM: The only step that calls an LLM is extract-reinforcement. Its model is set by
distill.extractionModelTier: unset → nano tier (e.g. gpt-4.1-nano);"default"(Expert/Full presets) → default tier;"nano"→ nano tier. Set to"default"or"nano"to avoid using your best model. Runopenclaw hybrid-mem verifyto see the current tier under “Ingestion & Distillation”. - When it runs: The job is already at night (Sunday 04:00). Ensure your OpenClaw cron/scheduler runs at that time so the pipeline doesn’t run during active use. After upgrading, if you run
openclaw hybrid-mem verify --fix, the job is re-created with the nano model; existing jobs keep their current model until you re-run install or verify –fix.
Scripts reference
All scripts live in scripts/ in this repo. Copy the ones you need to ~/.openclaw/scripts/.
Upgrade scripts
| Script | Purpose | When to use |
|---|---|---|
scripts/upgrade.sh | Runs npm update -g openclaw then post-upgrade.sh | Every time you upgrade OpenClaw |
scripts/post-upgrade.sh | Reinstalls deps in extension dir, restarts gateway | After any OpenClaw upgrade (manual or npm) |
Setup (one time):
mkdir -p ~/.openclaw/scripts
cp scripts/post-upgrade.sh scripts/upgrade.sh ~/.openclaw/scripts/
chmod +x ~/.openclaw/scripts/post-upgrade.sh ~/.openclaw/scripts/upgrade.sh
# Add alias to ~/.bashrc
echo "alias openclaw-upgrade='~/.openclaw/scripts/upgrade.sh'" >> ~/.bashrc
source ~/.bashrc
Then upgrade with: openclaw-upgrade
Environment variables for scripts:
| Variable | Default | Purpose |
|---|---|---|
OPENCLAW_MEMORY_EXTENSION | memory-hybrid | Extension name (change if using memory-lancedb) |
OPENCLAW_MEMORY_EXTENSION_DIR | Auto-detected via npm root -g | Override full path to extension dir |
Install and backfill scripts
| Script | Purpose | When to use |
|---|---|---|
scripts/install-hybrid-config.mjs | Writes full config defaults to openclaw.json | First install (before gateway exists) |
scripts/backfill-memory.mjs | Seeds plugin DBs from MEMORY.md + memory/**/*.md | After first install or adding new memory files |
Backfill:
EXT_DIR="$(npm root -g)/openclaw/extensions/memory-hybrid"
NODE_PATH="$EXT_DIR/node_modules" node scripts/backfill-memory.mjs
# Dry run first:
NODE_PATH="$EXT_DIR/node_modules" node scripts/backfill-memory.mjs --dry-run
| Variable | Default | Purpose |
|---|---|---|
OPENCLAW_WORKSPACE | ~/.openclaw/workspace | Workspace root to scan for memory files |
OPENCLAW_EXTENSION_DIR | Auto-detected | Extension dir for loading deps |
Task queue runner (scripts/task-queue.sh)
Cron and autonomous jobs (for example strategic-thinking) need a stable state/task-queue/current.json so prompts and dashboards see queue state. The plugin’s gateway watchdog can create an idle placeholder, but hosts that run jobs without the gateway still need a runner. This script delegates touch and status to openclaw hybrid-mem task-queue-touch / task-queue-status, and implements run so a shell command gets a proper lifecycle: claim the queue (after flock), write current.json with the child PID, move the finished entry under history/, then restore the idle placeholder. Concurrent mutating runs are skipped via flock (exit 0 for touch when another instance holds the lock; exit 2 for run so callers know work did not start). See issue #1000.
Setup: copy from the repo and mark executable: cp scripts/task-queue.sh ~/.openclaw/scripts/ && chmod +x ~/.openclaw/scripts/task-queue.sh.
# Ensure idle current.json exists (e.g. every 10 minutes)
*/10 * * * * OPENCLAW_HOME=$HOME/.openclaw $HOME/.openclaw/scripts/task-queue.sh touch >>$HOME/.openclaw/logs/task-queue.log 2>&1
# JSON for prompts (same as hybrid-mem task-queue-status)
$HOME/.openclaw/scripts/task-queue.sh status
# Wrap a job (PID recorded; history on exit)
$HOME/.openclaw/scripts/task-queue.sh run --title "Strategic thinking" --issue 1000 -- your-command.sh
Environment: OPENCLAW_HOME (default ~/.openclaw), TASK_QUEUE_STATE_DIR (optional override for state/task-queue), OPENCLAW_CMD (default openclaw), TASK_QUEUE_LOCKFILE (default /tmp/openclaw-task-queue.lock).
Valid current.json: The hybrid-memory plugin treats the file as a single current task or the canonical idle snapshot (status: "idle", producer: "openclaw-hybrid-memory"). External tools sometimes write metadata-only JSON (for example updatedAt, repo, maxForge) with no queue semantics. That is not a valid task payload and breaks automation that expects a real idle or work entry. The task-queue watchdog (gateway, every 5 minutes) archives such snapshots to history/*-degenerate.json and restores the idle placeholder; you can also run openclaw hybrid-mem task-queue-touch --repair. For planning visibility into ACTIVE-TASKS.md alongside the file, use openclaw hybrid-mem task-queue-status --with-active-tasks. See issue #1037.
Session distillation scripts
Located in scripts/distill-sessions/. See SESSION-DISTILLATION.md for full details.
| Script | Purpose |
|---|---|
batch-sessions.sh | Groups session logs into batches for processing |
| Nightly log output | Written to scripts/distill-sessions/nightly-logs/YYYY-MM-DD.md |
Upgrading OpenClaw
Important: After every OpenClaw upgrade, the plugin’s native dependencies (better-sqlite3, @lancedb/lancedb) can break because npm reinstalls the top-level package without touching extension directories.
→ Full guide: UPGRADE-OPENCLAW.md
Upgrade process
# Option 1: One-command upgrade (recommended)
openclaw-upgrade
# Option 2: Manual steps
npm update -g openclaw
~/.openclaw/scripts/post-upgrade.sh
# Option 3: Fully manual
npm update -g openclaw
cd "$(npm root -g)/openclaw/extensions/memory-hybrid"
npm install
openclaw gateway stop
openclaw gateway start
After upgrading
- Check logs for
memory-hybrid: initialized— confirms the plugin loaded. - Run
openclaw hybrid-mem verify— confirms DBs and embedding API work. - Run
openclaw hybrid-mem stats— confirms fact/vector counts are intact.
Why this is needed
Global npm upgrades reinstall the top-level openclaw package without running npm install inside extension directories. The plugin depends on native modules that need to be compiled for the current Node.js version and platform.
Upgrading the hybrid memory plugin
When a new version of this plugin is released:
→ Full guide: UPGRADE-PLUGIN.md
NPM install
openclaw plugins install openclaw-hybrid-memory
openclaw gateway stop && openclaw gateway start
openclaw hybrid-mem verify
Manual install
# 1. Copy new extension files
cp -r extensions/memory-hybrid/* "$(npm root -g)/openclaw/extensions/memory-hybrid/"
# 2. Install deps (in case package.json changed)
cd "$(npm root -g)/openclaw/extensions/memory-hybrid"
npm install
# 3. Restart
openclaw gateway stop && openclaw gateway start
# 4. Verify
openclaw hybrid-mem verify
Database migrations run automatically on startup. The plugin checks schemaVersion and applies any needed SQLite migrations. No manual migration step is required.
Config changes: New features may add optional config keys. Run openclaw hybrid-mem install --dry-run to see what defaults would be added, then openclaw hybrid-mem install to apply them.
Periodic maintenance checklist
These are optional but recommended for long-running systems:
| Task | Frequency | Command / Action |
|---|---|---|
| Verify health | Weekly or after changes | openclaw hybrid-mem verify |
| Review stats | Weekly | openclaw hybrid-mem stats |
| Find duplicates | Monthly | openclaw hybrid-mem find-duplicates --threshold 0.92 |
| Consolidate | Monthly (after review) | openclaw hybrid-mem consolidate --dry-run then consolidate |
| Entity / contact NER backfill | Monthly or after bulk import | openclaw hybrid-mem enrich-entities --limit 500 (fills PERSON/ORG rows when graph.enabled; see GRAPH-MEMORY.md) |
| Review memory files | Monthly | Read recent memory/YYYY-MM-DD.md, update memory/ files |
| Update MEMORY.md index | When files change | Edit MEMORY.md to reflect current structure |
| Archive completed projects | When done | Move from memory/projects/ to memory/archive/ |
| Run reflection | Monthly | openclaw hybrid-mem reflect --dry-run then reflect |
| Check distillation | Weekly (if enabled) | openclaw hybrid-mem verify shows last distillation run |
| Backfill after adding files | After adding many memory files | node scripts/backfill-memory.mjs |
File locations reference
| What | Default path | Override |
|---|---|---|
| OpenClaw config | ~/.openclaw/openclaw.json | OPENCLAW_HOME env var |
| SQLite database | ~/.openclaw/memory/facts.db | sqlitePath in plugin config |
| LanceDB directory | ~/.openclaw/memory/lancedb/ | lanceDbPath in plugin config |
| Write-ahead log | ~/.openclaw/memory/wal.jsonl | Adjacent to SQLite path |
| Discovered categories | ~/.openclaw/memory/.discovered-categories.json | Adjacent to SQLite path |
| Distillation last run | ~/.openclaw/memory/.distill_last_run | Adjacent to SQLite path |
| Credential vault | ~/.openclaw/memory/credentials.db | Adjacent to SQLite path |
| Workspace root | ~/.openclaw/workspace/ | OPENCLAW_WORKSPACE env var |
| Extension directory | $(npm root -g)/openclaw/extensions/memory-hybrid/ | OPENCLAW_MEMORY_EXTENSION_DIR env var |
| Upgrade scripts | ~/.openclaw/scripts/ | Copy from repo scripts/ |
For what to back up and how to restore, see BACKUP.md.
Gateway health polling (openclaw gateway status)
When you poll / monitor the gateway with openclaw gateway status, the CLI uses a default --timeout of 10000 ms (10s) for the WebSocket RPC probe. During warm-up (plugins loading, hybrid-memory databases opening), a single sample can exceed that window and report a probe failure even though the process is healthy.
Recommended for scripts and dashboards: use a longer timeout, for example:
openclaw gateway status --timeout 45000
Retry before treating a failure as real (e.g. 3 attempts with ~8s between samples). Full context and the misleading “Port 18789 is already in use” line when the probe path is unhappy: TROUBLESHOOTING.md § RPC health probe timeout (#938).
Related docs
- UPGRADE-OPENCLAW.md — What to do after every OpenClaw upgrade
- UPGRADE-PLUGIN.md — Upgrading the hybrid-memory plugin
- BACKUP.md — What to back up and how to restore
- UNINSTALL.md — Uninstalling the solution (revert to default memory)
- HOW-IT-WORKS.md — Runtime flow and what happens each turn
- QUICKSTART.md — Installation
- CONFIGURATION.md — Config reference
- CLI-REFERENCE.md — All CLI commands
- SESSION-DISTILLATION.md — Session distillation pipeline
- TROUBLESHOOTING.md — Common issues
- MAINTENANCE.md — File hygiene and periodic review