@milisp/codex-slim
v0.1.9
Published
Fast, lossless storage optimizer for Codex rollout and session logs.
Readme
codex-slim
Fast, lossless storage optimizer for Codex rollout and session logs.
Losslessly compresses oversized Codex CLI session (rollout-*.jsonl) files
on disk, in place, to codex's own .jsonl.zst format.
Why this is safe
codex-rs's own rollout reader (rollout/src/compression.rs::open_rollout_line_reader)
transparently reads both plain rollout-*.jsonl files and their .jsonl.zst
sibling, and automatically rehydrates a .jsonl.zst back to plain .jsonl
the moment a thread needs to append to it again (e.g. you codex resume and
keep chatting). So compressing a live rollout file to .jsonl.zst is safe:
codex resume reads it with no changes needed, and nothing is lost — it's
the same format codex uses for its own (currently experimental, default-off)
background compression worker, just applied on demand at a higher
compression level (zstd 19).
See docs/rollout-history-investigation.md
for the full investigation, including why whole-file compression was chosen
over per-item truncation (turn_context/reasoning duplication dominates disk
usage, and truncation can't touch that).
Install
npm install -g @milisp/codex-slimInstalls a prebuilt binary for your platform (macOS x64/arm64, Linux x64, Windows x64) — no Rust toolchain required.
Build from source
cargo build --release
# binary at ./target/release/codex-slimUsage
codex-slim [--dir <path>] [--threshold-mb <N>] [--min-age-days <N>] [--level <N>] [--move-to <path>] [--dry-run]--dir <path>Directory to scan recursively forrollout-*.jsonlfiles. Defaults to$CODEX_HOME/sessions, or~/.codex/sessionsifCODEX_HOMEis unset.--threshold-mb <N>(default5) Only touch files at or above this size. Pass0to check every file regardless of size.--min-age-days <N>(default3) Only touch files whose last modification is at least this many days old, so actively-resumed sessions aren't recompressed on every run. Pass0to disable the age filter. codex's own background compression worker uses 7.--level <N>(default19) zstd compression level (1-22). Higher means smaller output but slower.--move-to <path>After compressing, move the.jsonl.zstto this directory (e.g. a second disk), mirroring the original file's path relative to--dir, and leave a symlink at the original location socodex resumestill finds it there. Unix only.--dry-runReport what would change (estimated compressed size) without writing anything.--quietSuppress per-file output; only print the final summary if any files were compressed, plus errors. Intended for unattended/scheduled runs.
Running weekly in the background
All three run codex-slim --quiet every Sunday at 03:00 local time, using
the config file's defaults (or your edits to ~/.codex-slim/config.toml).
macOS (launchd user agent):
scripts/install-launchd.sh # remove: scripts/uninstall-launchd.shLogs go to ~/Library/Logs/dev.milisp.codex-slim.log.
Linux (systemd --user timer):
scripts/install-systemd.sh # remove: scripts/uninstall-systemd.shLogs via journalctl --user -u codex-slim.service.
Windows (Task Scheduler, PowerShell):
scripts/install-task-scheduler.ps1 # remove: scripts/uninstall-task-scheduler.ps1View/run the task from Task Scheduler Library > codex-slim.
Config file
On first run, codex-slim writes ~/.codex-slim/config.toml with the
defaults above, commented out, so you can edit it instead of retyping flags
every time:
threshold_mb = 5.0
min_age_days = 3
# move_to = "/mnt/archive/codex-sessions"
# dir = "/path/to/sessions"CLI flags always take precedence over the config file.
Examples
Preview what would happen to your real Codex sessions:
codex-slim --dry-runCompress anything over 5MB (defaults):
codex-slimCompress files over 1MB, moving the compressed output to a second disk:
codex-slim --threshold-mb 1 --move-to /mnt/archive/codex-sessionsRun against a specific CODEX_HOME (e.g. a test environment):
codex-slim --dir /tmp/omc/sessions --threshold-mb 5What happens on disk
For a file that gets compressed, e.g.:
rollout-2026-08-16T03-39-55-01a00983-....jsonlit's replaced in place by:
rollout-2026-08-16T03-39-55-01a00983-....jsonl.zst— codex's own compressed-sibling naming (plain file name with .zst
appended). The plain .jsonl file is removed only after the .jsonl.zst
is fully written. Nothing is truncated or edited; the compressed file
decompresses byte-for-byte identical to the original.
Files already ending in .jsonl.zst are skipped — already compressed.
To get the plain file back manually:
zstd -d rollout-....jsonl.zst(though this is normally unnecessary — codex rehydrates it automatically on resume).
Notes / limitations
- Only files matching codex's own naming (
rollout-*.jsonl) are touched; everything else in--diris ignored. --move-to(symlink-based relocation) works on Windows too, but creating a symlink there requires Developer Mode enabled or running as Administrator (Windows restrictsCreateSymbolicLinkotherwise); without either,--move-towill fail with a permission error.- Windows is otherwise fully supported, including via
npm install(default dirs resolve via%USERPROFILE%, and a prebuiltcodex-slim.exeis installed automatically same as on Unix).
Verified
Manually zstd-compressed a real session's rollout to .jsonl.zst and
called thread/resume against a real codex app-server — it read the
compressed file correctly (turns/items reconstructed, including
fileChange items), and the moment thread/resume attached a listener to
the thread, codex rehydrated the file back to plain .jsonl on disk by
itself. No custom restore step needed.
