Skip to content

perf: unbounded transcript files read whole into memory on resume (no rotation/compaction) #85

Description

@saucam

Summary

Transcript files grow without bound (no rotation, compaction, or truncation ever) and are read whole into memory on resume. The 20 s resume deadline is only checked between sessions, so a single huge transcript blocks daemon startup and can OOM.

Location

  • src/daemon/transcript.ts:207-224await file.text() then per-line JSON.parse of the entire file.
  • src/daemon/session-manager.ts:133-139 — resume deadline checked between sessions only.
  • write amplification: up to three full JSONL lines per tool call — session.ts:1940 (tool_start), :1609 (approval resolution), :1966 (completion including full tool output).
  • restoreScrollback re-stringifies every historical message for size accounting even though only the last 5000 / 20 MB survive eviction.

Failure scenario

A months-old autonomous session accumulates a 300 MB–1 GB transcript. On restart, resume calls file.text() — the whole read/parse runs under no deadline (the check is only between sessions), blocking startup and risking OOM. packSession (export) hits the same full read on demand.

Fix

Rotate/segment transcripts (size- or time-based) with an index; stream-parse on resume with the deadline applied within a file; cap per-episode persisted output; drop the full re-stringify in restoreScrollback (track sizes incrementally).

Metadata

Metadata

Assignees

No one assigned

    Labels

    auditSurfaced in a code auditperfPerformance and scalabilityrobustnessProduction-grade robustness gaps

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions