Why are Rust executables so huge?

By default, the Rust compiler optimizes for execution speed, compilation speed, and ease of debugging (by including symbols, for example), rather than minimal binary size.

For an overview of all of the ways to reduce the size of a Rust binary, see the min-sized-rust repository.

The current high level steps to reduce binary size are:

  1. Use Rust 1.32.0 or newer (which doesn't include jemalloc by default)
  2. Add the following to Cargo.toml:
[profile.release]
opt-level = 'z'     # Optimize for size.
lto = true          # Enable Link Time Optimization
codegen-units = 1   # Reduce number of codegen units to increase optimizations.
panic = 'abort'     # Abort on panic
strip = true        # Strip symbols from binary*

*strip = true requires Rust 1.59+. On older Rust versions, run strip manually on the resulting binary.

  1. Build in release mode using cargo build --release

There is more that can be done using nightly Rust, but I'll leave that information in min-sized-rust as it changes over time due to the use of unstable features.

You can also use #![no_std] to remove Rust's libstd. See min-sized-rust for details.


Rust uses static linking to compile its programs, meaning that all libraries required by even the simplest Hello world! program will be compiled into your executable. This also includes the Rust runtime.

To force Rust to dynamically link programs, use the command-line arguments -C prefer-dynamic; this will result in a much smaller file size but will also require the Rust libraries (including its runtime) to be available to your program at runtime. This essentially means you will need to provide them if the computer does not have them, taking up more space than your original statically linked program takes up.

For portability I'd recommend you statically link the Rust libraries and runtime in the way you have been doing if you were to ever distribute your programs to others.