Link-time optimization (especially fat LTO) merges every crate into one module for the optimizer, multiplying peak memory. On a memory-tight runner LLVM aborts with an out-of-memory error during codegen.
What this error means
The build fails late, during the final codegen/link, with LLVM ERROR: out of memory or an OOM kill of the codegen process. It appears with lto = "fat" or lto = true release profiles.
cargo
LLVM ERROR: out of memory
Allocation failed
error: could not compile `app` (bin "app")
# during the LTO codegen phase of a --release build
Diagnose it: linker, target, or memory
Rust build failures in CI that are not compiler errors are usually a missing system linker or library, a target that is not installed, or the compiler being killed for memory.
Terminal
rustup target list --installed
cc --version || echo "no C toolchain: install build-essential"
free -h
# exit 137 during codegen is an out-of-memory kill, not a compile error
cargo build -j 2 # fewer parallel codegen units uses less memory
Common causes
Fat LTO holds the whole program in memory
lto = "fat" (or true) merges all crates into one LLVM module, so peak memory scales with total program size and overruns the runner.
High codegen parallelism during LTO
Multiple parallel codegen threads each consume memory, compounding the LTO peak.
# Cargo.toml
[profile.release]
lto = "thin" # or lto = false for CI builds
codegen-units = 16
Build on a larger-memory runner
.github/workflows/ci.yml
runs-on:latchkey-large
How to prevent it
Prefer lto = "thin" over fat LTO in CI.
Reserve fat LTO for release artifacts built on high-memory hosts.
On self-healing managed runners (Latchkey), an OOM during LTO codegen is auto-retried with larger RAM and the registry is cached, so a memory spike does not break the build.
Frequently asked questions
What causes Rust "ran out of memory" during LTO codegen in CI?
There are 2 common causes: fat lto holds the whole program in memory and high codegen parallelism during lto. lto = "fat" (or true) merges all crates into one LLVM module, so peak memory scales with total program size and overruns the runner.
How do I fix Rust "ran out of memory" during LTO codegen in CI?
There are 2 fixes depending on which cause you have: use thin lto or disable it for ci and build on a larger-memory runner. Work through them in order, since the first is the most common.
What does Rust "ran out of memory" during LTO codegen in CI actually mean?
The build fails late, during the final codegen/link, with LLVM ERROR: out of memory or an OOM kill of the codegen process.
How do I stop Rust "ran out of memory" during LTO codegen in CI happening again?
Prefer lto = "thin" over fat LTO in CI. The prevention section lists 3 changes that keep it from recurring.
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.