Criterion Benchmark Temp DB No Space Left On Device
A Rust benchmark can look like a database bug when the real failure is storage pressure: each Criterion iteration creates a fresh SQLite database or fixture tree, the teardown boundary is missing, and /tmp or $TMPDIR fills before the run finishes.
Get the exact cleanup order before deleting.
Run the free CI storage Action first, then send one request only if the failure still needs judgment. The job link, log excerpt, or storage summary can follow after the first reply.
Fast diagnosis
Run these read-only checks before deleting anything. They separate a full filesystem from a benchmark that leaks per-iteration temp state.
echo "== filesystems =="
df -h /tmp "${TMPDIR:-/tmp}" 2>/dev/null || true
echo "== likely benchmark temp databases =="
find /tmp "${TMPDIR:-/tmp}" -maxdepth 1 \( -name 'rag-rat-bench-*' -o -name '*bench*.sqlite' -o -name '*criterion*' \) -print 2>/dev/null | head -80
echo "== largest matching temp entries =="
du -sh /tmp/rag-rat-bench-* "${TMPDIR:-/tmp}"/*bench*.sqlite 2>/dev/null | sort -h | tail -30
What usually happened
iter_batchedor similar setup creates a new temp DB, fixture checkout, or generated corpus for each iteration.- The setup returns only the database path or handle, so the owning temp directory is dropped too early or never cleaned.
- Criterion sample count multiplies the peak size: 50 iterations at 1.5GB each can consume 75GB even when one iteration looks reasonable.
- SQLite then reports
database or disk is full, or the runner showsNo space left on device.
Safer benchmark fixes
- Make the temp directory the owned batched input, then drop it after the measured closure finishes.
- Use a dedicated benchmark temp root so cleanup cannot touch unrelated
/tmpentries. - Add a post-run assertion that no benchmark-owned temp paths remain.
- Log
df -hand top temp entries before and after the benchmark in CI. - Lower sample count only as a mitigation; it should not be the root fix if temp ownership is leaking.
Use this when a benchmark fills /tmp.
This keeps the thread focused on ownership and teardown instead of broad system cleanup.
I would treat this as a benchmark temp ownership bug, not just a low-disk runner problem.
The useful checks are:
- df -h /tmp "$TMPDIR" before and after the benchmark
- top benchmark-owned temp paths after a failed run
- whether each iter_batched setup creates a fresh DB/fixture tree
- whether the owning TempDir is kept alive until teardown
- a post-run assertion that no benchmark-owned temp paths remain
The durable fix is to make each generated DB or fixture tree owned by a scoped temp directory and drop/remove it after the measured iteration. Lowering Criterion samples only reduces the blast radius.
Do not delete first
- Arbitrary
/tmpcontents while tests, databases, or browsers are still running. - Open SQLite files, WAL files, or fixture directories that an active benchmark process still owns.
- CI logs, flamegraphs, Criterion reports, or failure artifacts before they are uploaded.
Turn the failing run into a cleanup order
The $29 Deep Cleanup reviews one benchmark failure, CI log, or storage scan and returns the exact safe cleanup order, temp ownership fix, and do-not-touch paths.
Need a cleanup order for this runner?
Submit the form first; the failing job link can follow. We check whether free guidance is enough before asking for the $29 Deep Cleanup.