CI Runner Swap Exhausted / Thrashing - Slow Then OOM
By Daniel Zoghalchali·Latchkey
When RAM runs out, the kernel pushes pages to swap. If swap is small or also full, the runner thrashes - spending all its time paging - and then the OOM killer steps in anyway.
What this error means
A step that normally takes minutes hangs for far longer, the runner becomes unresponsive, and the job eventually dies with Killed/exit 137 or times out. CPU looks idle while disk I/O is pegged - the classic swap-thrash profile.
CI log
# the job stalls, then:
Killed
##[error] Process completed with exit code 137.
# vmstat shows constant si/so (swap in/out) before the kill
Common causes
Memory pressure pushed the job into swap
Peak memory exceeded RAM, so the kernel paged to disk. Swap is orders of magnitude slower than RAM, so throughput collapses.
Swap is small, full, or disabled
Many CI runners have little or no swap. Once it fills, the kernel can no longer offload pages and the OOM killer terminates the heaviest process.
How to fix it
Confirm swap pressure
Look at swap usage and paging activity to confirm thrashing.
Terminal
free -m
vmstat 1 5 # watch the si/so columns for sustained paging
Reduce memory use or add RAM
Move to a runner with more physical RAM so the job stays in memory.
Lower peak usage (parallelism, heap size, batch sizes) so it never spills to swap.
Avoid relying on swap for CI throughput - treat swapping as a warning, not a buffer.
How to prevent it
Size runners so the working set fits in RAM with headroom.
Monitor si/so paging activity in long jobs.
Do not rely on swap to absorb build memory spikes.
Frequently asked questions
What causes "Swap exhausted / thrashing"?
Peak memory exceeded RAM, so the kernel paged to disk. Swap is orders of magnitude slower than RAM, so throughput collapses.
How do I fix Swap exhausted / thrashing?
Look at swap usage and paging activity to confirm thrashing.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.