You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Retained process output holds one open file descriptor per job for 24 hours #634
Each retained background-process record keeps its output spool (data/process-output/<generation>.out) open as a file descriptor for the whole 24-hour retention window. _restore_output() reopens every retained spool when the lazily created process registry first starts, so descriptors jump all at once, and the count scales with background jobs run per day. Odin's service runs with the default soft limit of 1024 open files. A busy day of background jobs can push it toward EMFILE ("Too many open files"), at which point unrelated sockets, SQLite, SSH and HTTP work start failing.
Evidence (live, 2026-09-30, v4.11.0)
Odin's process held 209 descriptors, and 182 of them were process-output/<gen>.out spools.
The count went from 33 to 220 the moment the registry was first created in that process: the first manage_process call restored about 180 retained records and opened each spool.
Background starts per day from the audit log: the peak was 326 (2026-09-29), then 177 and 128. At one spool descriptor per job held for 24 h, the peak day alone is about a third of the soft limit, before sockets, databases, pipes and MCP transports.
The behaviour is the same in v4.10.0 (info.spool = spool_path.open("rb") in _restore_output), so it is not a v4.11.0 regression.
Expected
Retained output should not hold a descriptor per job. For example, open the spool on demand for a poll/get_tool_output read and close it afterwards; or close finished jobs' spools and reopen lazily.
Restoring retained records at registry creation should not open their spools eagerly.
Keep retention semantics and cursor validity unchanged.
Impact
Every install that runs many manage_process jobs (agents running test suites, long builds). The failure mode is non-local: descriptor exhaustion breaks unrelated subsystems.
Activity
fix(processes): release retained spool descriptors and report file he…
Calmingstorm commentedon Oct 1, 2026
Fixed in v4.12.0 (PR #635): https://github.com/Calmingstorm/Odin/releases/tag/v4.12.0