openclaw - ✅(Solved) Fix feat: sessions cleanup should remove physical .deleted and .reset files, not only index entries [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

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…
GitHub stats
openclaw/openclaw#75658Fetched 2026-05-02 05:32:10
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
2
Author
Timeline (top)
cross-referenced ×2commented ×1referenced ×1

openclaw sessions cleanup only manages entries in sessions.json (the index), but does not remove the physical .deleted.* and .reset.* files from disk. These files accumulate indefinitely, causing the session store to grow to hundreds of MB, which worsens the event-loop-blocking issue from synchronous session reads (related: #75656).

Error Message

After normal usage over several weeks, main/sessions/ accumulated:

Root Cause

The Gateway reads session state using synchronous fs.readFileSync() (see related issue #75656). The larger the sessions/ directory, the longer these blocking reads take. Without automatic GC, the store grows without bound and the performance degradation is progressive — getting worse with every session reset or deletion until a manual intervention.

Additionally, the session store also contains .checkpoint.* files for sessions that no longer exist in the index. These are also not cleaned up:

# Example: 8 orphaned checkpoint files = 16.9 MB
df7e7ea4...checkpoint.457b...jsonl   5.7 MB  (session not in index)
df7e7ea4...checkpoint.5fe9...jsonl   4.3 MB
df7e7ea4...checkpoint.54eb...jsonl   2.6 MB
95e56fe8...checkpoint.a790...jsonl   1.0 MB

Fix Action

Fixed

PR fix notes

PR #75672: feat(sessions): clean up archived transcript files on cleanup (#75658)

Description (problem / solution / changelog)

Fixes #75658.

Problem

openclaw sessions cleanup only manages entries in sessions.json (the index). The on-disk archive artefacts that the gateway leaves behind during normal use accumulate indefinitely:

  • <sessionId>.jsonl.deleted.<ts> (explicitly-deleted sessions)
  • <sessionId>.jsonl.reset.<ts> (post-/reset snapshots)
  • <sessionId>.checkpoint.<uuid>.jsonl for sessions that are no longer in the index (orphan compaction checkpoints)

The reporter saw 63 MB of archived files vs 36 MB of live state on a busy Pi install. openclaw sessions cleanup --all-agents --dry-run reported Would prune missing transcripts: 0 despite 86 archive files.

This compounds the synchronous-fs.readFileSync event-loop blocking discussed in #75656 — the bigger the directory, the worse the wedges.

Why the gateway already had the helper

cleanupArchivedSessionTranscripts() (in src/gateway/session-archive.runtime.ts) already implements the timestamp-based pruning logic. The gateway calls it inline during normal maintenance (src/config/sessions/store.ts lines 347–363). The CLI just never wired it up.

Fix

Add planArchivedSessionFileCleanup() to the sessions cleanup command:

  1. Scan the directory containing the session store.
  2. .deleted.<ts> older than maintenance.pruneAfterMs → remove.
  3. .reset.<ts> older than maintenance.resetArchiveRetentionMs → remove (skipped when retention is null, matching existing runtime behaviour — operators opt in via sessionMaintenance.resetArchiveRetention).
  4. <sessionId>.checkpoint.<uuid>.jsonl whose sessionId is no longer in the live index → remove.
  5. Honours --dry-run (preview) and --enforce (apply).

The plan is surfaced in:

  • The dry-run summary log: Would remove archived transcripts: N (deleted=, reset=, orphan-checkpoint=, B bytes) (or Archived transcripts scanned: N (none past retention) when nothing qualifies).
  • A new archivedFiles field on SessionCleanupSummary (and therefore the JSON output).

Tests

New sessions-cleanup.archived-files.test.ts covers four cases:

  • dry-run reports candidates without deleting any files
  • apply removes .deleted, .reset, and orphan checkpoints, while preserving in-window archives, live checkpoints, the unrelated sessions.json, and non-session files
  • resetArchiveRetentionMs: null preserves all .reset files but .deleted files are still removed via pruneAfterMs
  • a missing store directory returns an empty plan instead of throwing

The logic was first validated with a standalone fs-based simulator before being mirrored into the test file. All cases pass.

The pre-existing sessions-cleanup.test.ts continues to work — it already supplies resetArchiveRetentionMs in the mocked maintenance config and the new helper handles missing on-disk directories silently.

Risk

Medium-low. The helper:

  • Uses the existing archive-timestamp parser (parseSessionArchiveTimestamp) so it cannot mis-identify non-archive files.
  • Only acts inside the directory of the configured store.
  • Honours both retention thresholds that the gateway already enforces via cleanupArchivedSessionTranscripts.
  • Treats the store directory not existing as a no-op.
  • Treats unlink failures as best-effort (matches cleanupArchivedSessionTranscripts).

The directory walk is fs.readdirSync + fs.statSync per file. Pi/ARM users with hundreds of MB of archive files will see a one-time pause during cleanup; this matches the gateway-side maintenance path that is already on the same code shape.

Changed files

  • CHANGELOG.md (modified, +2/-0)
  • docs/cli/sessions.md (modified, +25/-0)
  • src/commands/sessions-cleanup.archived-files.test.ts (added, +180/-0)
  • src/commands/sessions-cleanup.ts (modified, +224/-2)

Code Example

Total size:              116 MB
.deleted.* files:        71 files  =  51 MB   ← sessions explicitly deleted
.reset.* files:          15 files  =  12 MB   ← old states after session reset
orphaned .checkpoint.*:   8 files  =  17 MB   ← checkpoints for deleted sessions
sessions.json index:      1 file   = 722 KB   ← read synchronously by gateway

---

Agent: main
Entries: 36 -> 36 (remove 0)
Would prune missing transcripts: 0
Would prune stale: 0
Would cap overflow: 0

---

# Example: 8 orphaned checkpoint files = 16.9 MB
df7e7ea4...checkpoint.457b...jsonl   5.7 MB  (session not in index)
df7e7ea4...checkpoint.5fe9...jsonl   4.3 MB
df7e7ea4...checkpoint.54eb...jsonl   2.6 MB
95e56fe8...checkpoint.a790...jsonl   1.0 MB
RAW_BUFFERClick to expand / collapse

Summary

openclaw sessions cleanup only manages entries in sessions.json (the index), but does not remove the physical .deleted.* and .reset.* files from disk. These files accumulate indefinitely, causing the session store to grow to hundreds of MB, which worsens the event-loop-blocking issue from synchronous session reads (related: #75656).

Environment

  • OS: Raspberry Pi, Linux 6.12.75+rpt-rpi-v8, arm64/aarch64
  • Node.js: v24.14.1
  • OpenClaw: 2026.4.29 (a448042)
  • Affected agent: main (heavy usage with dreaming enabled)

Observed behavior

After normal usage over several weeks, main/sessions/ accumulated:

Total size:              116 MB
.deleted.* files:        71 files  =  51 MB   ← sessions explicitly deleted
.reset.* files:          15 files  =  12 MB   ← old states after session reset
orphaned .checkpoint.*:   8 files  =  17 MB   ← checkpoints for deleted sessions
sessions.json index:      1 file   = 722 KB   ← read synchronously by gateway

Running openclaw sessions cleanup --all-agents --dry-run reports:

Agent: main
Entries: 36 -> 36 (remove 0)
Would prune missing transcripts: 0
Would prune stale: 0
Would cap overflow: 0

0 files would be removed, despite 86 explicitly-deleted/reset files taking up 63 MB on disk.

After manual deletion of .deleted.* and .reset.* files: 116 MB → 36 MB (−69%).

Why this matters

The Gateway reads session state using synchronous fs.readFileSync() (see related issue #75656). The larger the sessions/ directory, the longer these blocking reads take. Without automatic GC, the store grows without bound and the performance degradation is progressive — getting worse with every session reset or deletion until a manual intervention.

Additionally, the session store also contains .checkpoint.* files for sessions that no longer exist in the index. These are also not cleaned up:

# Example: 8 orphaned checkpoint files = 16.9 MB
df7e7ea4...checkpoint.457b...jsonl   5.7 MB  (session not in index)
df7e7ea4...checkpoint.5fe9...jsonl   4.3 MB
df7e7ea4...checkpoint.54eb...jsonl   2.6 MB
95e56fe8...checkpoint.a790...jsonl   1.0 MB

Suggested behavior

openclaw sessions cleanup (with --enforce or a new --purge-files flag) should:

  1. Delete physical .jsonl.deleted.* files for sessions marked as deleted
  2. Delete physical .trajectory.jsonl.deleted.* files for deleted sessions
  3. Delete physical .jsonl.reset.* files (superseded by current session state)
  4. Delete .checkpoint.*.jsonl files whose session ID is no longer present in the index
  5. Optionally: delete .trajectory.jsonl files for sessions beyond a configurable retention count

A --dry-run mode should report these physical files separately from index entries so users can see the actual disk impact.

Related

  • #75656 — synchronous session reads block event loop; large session store makes this progressively worse

extent analysis

TL;DR

The openclaw sessions cleanup command should be modified to delete physical files associated with deleted or reset sessions to prevent the session store from growing indefinitely.

Guidance

  • The current implementation of openclaw sessions cleanup only manages entries in sessions.json and does not remove physical files, leading to accumulation of .deleted.* and .reset.* files.
  • To mitigate this issue, consider adding a new flag, such as --purge-files, to openclaw sessions cleanup to delete physical files for deleted or reset sessions.
  • The command should also delete .checkpoint.*.jsonl files whose session ID is no longer present in the index to prevent orphaned checkpoint files.
  • A --dry-run mode should be implemented to report the physical files that would be deleted, allowing users to see the actual disk impact.

Example

No code snippet is provided as the issue does not contain sufficient information about the implementation details of openclaw sessions cleanup.

Notes

The suggested behavior for openclaw sessions cleanup includes deleting physical files for deleted or reset sessions, which may have implications for data retention and recovery. It is essential to consider these implications before implementing the suggested changes.

Recommendation

Apply a workaround by manually deleting the physical files associated with deleted or reset sessions until a permanent fix is implemented. This will prevent the session store from growing indefinitely and mitigate the performance degradation caused by synchronous session reads.

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

openclaw - ✅(Solved) Fix feat: sessions cleanup should remove physical .deleted and .reset files, not only index entries [1 pull requests, 1 comments, 2 participants]