The README promises a bound the hook does not enforce on three of the five cache volumes.
README.md (X64 cache volumes):
Budget ~20 GB per runner (enforced by the post-job hook with LRU, not a wipe), ~60 GB per beelink.
cleanup.sh calls lru_cap twice:
lru_cap /root/.gradle
lru_cap /root/.bun
docker-compose.yml mounts five cache volumes per runner. /root/.cargo, /root/.npm and /root/.cache/pnpm have no cap, so the ~20 GB per-runner budget is not what the host actually gets — three volumes grow until the beelink disk does.
Cargo is the one that bites first: ~/.cargo/registry (src + cache) plus git checkouts grows monotonically across dependency-set changes, and nothing in the image ever evicts from it. pnpm's content-addressable store has the same shape — it only ever accretes, since the store is shared across every project the runner has ever built.
lru_cap already takes a directory argument and does the right thing, so this is likely three more calls:
lru_cap /root/.gradle
lru_cap /root/.bun
lru_cap /root/.cargo
lru_cap /root/.npm
lru_cap /root/.cache/pnpm
Worth deciding whether CACHE_CAP_BYTES should stay one shared per-directory value or become per-store. Five directories each capped at 20 GiB is a 100 GB per-runner ceiling, i.e. 300 GB per beelink — which is not the "~60 GB per beelink" the README states either. Either the cap becomes a per-runner total split across stores, or the README number changes to match whatever is actually enforced.
One caveat on extending lru_cap as written: it evicts oldest regular files by mtime, which is safe for a content-addressed tarball store but less so for a tree where a file is only meaningful alongside its siblings. ~/.cargo/registry/src unpacked sources and pnpm store entries are both hard-linked into project node_modules / target dirs, so a partial eviction can leave a project tree pointing at files that are gone. Capping ~/.cargo/registry/cache (the .crate archives) rather than all of ~/.cargo may be the safer shape.
Context: dodi-smart/.github PR #6 puts self-hosted X64 jobs on these home dirs precisely so the volumes are read, which makes the cap the only thing standing between a busy beelink and a full disk.
The README promises a bound the hook does not enforce on three of the five cache volumes.
README.md(X64 cache volumes):cleanup.shcallslru_captwice:docker-compose.ymlmounts five cache volumes per runner./root/.cargo,/root/.npmand/root/.cache/pnpmhave no cap, so the ~20 GB per-runner budget is not what the host actually gets — three volumes grow until the beelink disk does.Cargo is the one that bites first:
~/.cargo/registry(src + cache) plus git checkouts grows monotonically across dependency-set changes, and nothing in the image ever evicts from it. pnpm's content-addressable store has the same shape — it only ever accretes, since the store is shared across every project the runner has ever built.lru_capalready takes a directory argument and does the right thing, so this is likely three more calls:Worth deciding whether
CACHE_CAP_BYTESshould stay one shared per-directory value or become per-store. Five directories each capped at 20 GiB is a 100 GB per-runner ceiling, i.e. 300 GB per beelink — which is not the "~60 GB per beelink" the README states either. Either the cap becomes a per-runner total split across stores, or the README number changes to match whatever is actually enforced.One caveat on extending
lru_capas written: it evicts oldest regular files by mtime, which is safe for a content-addressed tarball store but less so for a tree where a file is only meaningful alongside its siblings.~/.cargo/registry/srcunpacked sources and pnpm store entries are both hard-linked into projectnode_modules/ target dirs, so a partial eviction can leave a project tree pointing at files that are gone. Capping~/.cargo/registry/cache(the.cratearchives) rather than all of~/.cargomay be the safer shape.Context:
dodi-smart/.githubPR #6 puts self-hosted X64 jobs on these home dirs precisely so the volumes are read, which makes the cap the only thing standing between a busy beelink and a full disk.