#9438: fix: auto-detect low-memory environments and prevent test OOM
scripts
stale
Cluster:
Memory Management Enhancements
## Problem
On machines with < 6GB RAM, running `pnpm test` causes OOM kills due to:
- Two test groups (unit + extensions) running in parallel via `Promise.all`
- Each using 4+ vitest workers (minimum enforced by `localWorkers = Math.max(4, ...)`)
- Combined with file parallelism, peak memory usage exceeds available RAM
Tested on a 4GB / 2-core Azure VM where `pnpm test` consistently got killed by the OOM killer.
## Solution
Add automatic low-memory detection that:
- Runs all test groups **serially** instead of in parallel
- Uses only **1 vitest worker** to minimize memory footprint
- Disables file parallelism via `--no-file-parallelism`
- Shows a warning message when low-memory mode is active
## Triggering Conditions
- System has < 6GB total RAM (auto-detected via `os.totalmem()`)
- Or `OPENCLAW_TEST_LOWMEM=1` is set manually
## Backwards Compatibility
- **CI unaffected**: GitHub Actions runners have sufficient memory, so no behavior change
- **Existing overrides work**: `OPENCLAW_TEST_WORKERS` still takes precedence
- **No config changes needed**: Works automatically on low-memory machines
## Trade-offs
| Aspect | Before | After (low-mem) |
|--------|--------|-----------------|
| Parallel groups | 2 (unit + extensions) | 0 (all serial) |
| Workers per group | 4+ | 1 |
| Test speed | ~X min | ~3-4X min |
| Memory usage | OOM 💀 | ~2GB ✅ |
The slowdown is acceptable for development machines where the alternative is tests not running at all.
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates `scripts/test-parallel.mjs` to auto-detect low-memory machines (or honor `OPENCLAW_TEST_LOWMEM=1`) and, when triggered, run all Vitest groups serially, disable file parallelism, and force a single worker to reduce peak memory usage. It keeps existing CI- and OS-specific behaviors (e.g., Windows CI sharding and warning suppression) while adding a local-only warning banner when low-memory mode is active.
<h3>Confidence Score: 3/5</h3>
- This PR is close to safe to merge but contains a functional issue that can nullify the intended low-memory protection.
- The overall approach (serializing runs and disabling file parallelism) is straightforward, but the worker-limit flag appears to be passed with the wrong spelling, which would cause Vitest to ignore it and defeats the main OOM mitigation on low-memory machines.
- scripts/test-parallel.mjs
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#21295: test: guard test runner memory on local runs
by vincentkoc · 2026-02-19
80.8%
#11158: doctor: warn when system RAM is at or below 2 GB (deafult in the mo...
by jasonthewhale · 2026-02-07
73.6%
#21217: fix: memory prune command to prevent unbounded MEMORY.md growth
by theognis1002 · 2026-02-19
73.5%
#12596: fix(status): show third-party memory plugins as active instead of u...
by nhadaututtheky · 2026-02-09
72.7%
#19112: fix(memory): prevent OOM on memory_get with large files
by Clawborn · 2026-02-17
72.3%
#2884: fix: Create memory directory and symlink identity files during work...
by webdevtodayjason · 2026-01-27
72.2%
#6060: feat(onboarding): add Memory Optimization step to onboarding wizard
by GodsBoy · 2026-02-01
71.8%
#15945: fix(memory-flush): only write memoryFlushCompactionCount when compa...
by aldoeliacim · 2026-02-14
71.7%
#19063: CI/macOS: disable Vitest vmForks for TS tests to stop mock-state le...
by agisilaos · 2026-02-17
71.5%
#4999: fix(memory-flush): use contextTokens instead of totalTokens for thr...
by Farfadium · 2026-01-30
71.2%