@milisp/codex-slim

Fast, lossless storage optimizer for Codex rollout and session logs.


Keywords
codex
License
MIT
Install
npm install @milisp/codex-slim@0.1.9

Documentation

codex-slim

npm downloads

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-slim

Installs 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-slim

Usage

codex-slim [--dir <path>] [--threshold-mb <N>] [--min-age-days <N>] [--level <N>] [--move-to <path>] [--dry-run]
  • --dir <path> Directory to scan recursively for rollout-*.jsonl files. Defaults to $CODEX_HOME/sessions, or ~/.codex/sessions if CODEX_HOME is unset.

  • --threshold-mb <N> (default 5) Only touch files at or above this size. Pass 0 to check every file regardless of size.

  • --min-age-days <N> (default 3) Only touch files whose last modification is at least this many days old, so actively-resumed sessions aren't recompressed on every run. Pass 0 to disable the age filter. codex's own background compression worker uses 7.

  • --level <N> (default 19) zstd compression level (1-22). Higher means smaller output but slower.

  • --move-to <path> After compressing, move the .jsonl.zst to this directory (e.g. a second disk), mirroring the original file's path relative to --dir, and leave a symlink at the original location so codex resume still finds it there. Unix only.

  • --dry-run Report what would change (estimated compressed size) without writing anything.

  • --quiet Suppress 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.sh

Logs go to ~/Library/Logs/dev.milisp.codex-slim.log.

Linux (systemd --user timer):

scripts/install-systemd.sh    # remove: scripts/uninstall-systemd.sh

Logs via journalctl --user -u codex-slim.service.

Windows (Task Scheduler, PowerShell):

scripts/install-task-scheduler.ps1    # remove: scripts/uninstall-task-scheduler.ps1

View/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-run

Compress anything over 5MB (defaults):

codex-slim

Compress files over 1MB, moving the compressed output to a second disk:

codex-slim --threshold-mb 1 --move-to /mnt/archive/codex-sessions

Run against a specific CODEX_HOME (e.g. a test environment):

codex-slim --dir /tmp/omc/sessions --threshold-mb 5

What happens on disk

For a file that gets compressed, e.g.:

rollout-2026-08-16T03-39-55-01a00983-....jsonl

it'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 --dir is ignored.
  • --move-to (symlink-based relocation) works on Windows too, but creating a symlink there requires Developer Mode enabled or running as Administrator (Windows restricts CreateSymbolicLink otherwise); without either, --move-to will fail with a permission error.
  • Windows is otherwise fully supported, including via npm install (default dirs resolve via %USERPROFILE%, and a prebuilt codex-slim.exe is 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.