johnthagen /min-sized-rust

🦀 How to minimize Rust binary size 📦 https://github.com/johnthagen/min-sized-rust

★ 9,870⑂ 248👁 108⑃ 41● 42▤ 0
RustCreated 2018-12-09
9,870
stars
+0+-1+14
248
forks
108
watchers
41
prs
42
issues
0
releases
–
discussions

README

Minimizing Rust Binary Size

[![GitHub Actions][github-actions-badge]](https://github.com/johnthagen/min-sized-rust/actions)

[github-actions-badge]: https://github.com/johnthagen/min-sized-rust/workflows/build/badge.svg

This repository demonstrates how to minimize the size of a Rust binary.

By default, Rust optimizes for execution speed, compilation speed, and ease of debugging
rather than binary size, since for the vast majority of applications this is ideal. But
for situations where a developer wants to optimize for binary size instead, Rust provides
mechanisms to accomplish this.

 Build in Release Mode

!Minimum Rust: 1.0

By default, cargo build builds the Rust binary in debug mode. Debug mode disables many
optimizations, which helps debuggers (and IDEs that run them) provide a better debugging
experience. Debug binaries can be 30% or more larger than release binaries.

To minimize binary size, build in release mode:

bash
$ cargo build --release


 strip Symbols from Binary

!OS: nix
!Minimum Rust: 1.59

By default on Linux and macOS, symbol information is included in the compiled .elf file. This
information is not needed to properly execute the binary.

Cargo can be configured to
automatically strip binaries.
Modify Cargo.toml in this way:

toml
[profile.release]
strip = true   Automatically strip symbols from the binary.


Prior to Rust 1.59, run strip directly on
the .elf file instead:

bash
$ strip target/release/min-sized-rust


 Optimize For Size

!Minimum Rust: 1.28

[Cargo defaults its optimization level to 3 for release builds][cargo-profile],
which optimizes the binary for speed. To instruct Cargo to optimize for minimal binary
size, use the z optimization level in
Cargo.toml:

[cargo-profile]: https://doc.rust-lang.org/cargo/reference/profiles.htmldefault-profiles

toml
[profile.release]
opt-level = "z"   Optimize for size.


 [!NOTE]
 In some cases the "s" level may result in a smaller binary than "z", as explained in the
 opt-level documentation:
 
 It is recommended to experiment with different levels to find the right balance for your project.
 There may be surprising results, such as ... the "s" and "z" levels not being necessarily
 smaller.

 Enable Link Time Optimization (LTO)

!Minimum Rust: 1.0

By default,
[Cargo instructs compilation units to be compiled and optimized in isolation][cargo-profile].
LTO instructs the linker to optimize at the
link stage. This can, for example, remove dead code and often times reduces binary size.

Enable LTO in Cargo.toml:

toml
[profile.release]
lto = true


 Dynamic Linking: Why It Doesn't Work

!Minimum Rust: 1.0

Some might suggest using prefer-dynamic for smaller binaries, but this approach has critical limitations:

- No stable ABI - binaries break between Rust versions
- Deployment complexity - requires exact library matches
- Community consensus - static linking preferred for reliability

 Reduce Parallel Code Generation Units to Increase Optimization

[By default][cargo-profi

Snapshot: 2026-11-04T14:00:00Z · Data license Apache-2.0 · JSON