Rust Release Optimization: How to Build Small and Fast Binaries
James Reed
Infrastructure Engineer · Leapcell

You have completed writing a Rust project and are now working on compilation. How can you make the compiled file as small as possible? How can you make it run as fast as possible? Or how can you achieve both small size and high speed?
You may have these considerations:
- Minimizing file size: Suitable for embedded development, where the project is small and not complex, and execution speed is already fast. The main goal is to reduce the file size as much as possible.
- Maximizing execution speed: Suitable for network services where file size is not a concern, but maximizing concurrency is the top priority.
- Balancing both size and speed: A middle ground that is suitable for various types of projects.
You only need to add the following configuration to your Cargo.toml
file and run:
cargo b --release
Configuration Examples
Generate a Smaller Executable
[profile.release] opt-level = "z" # Optimize for the smallest code size lto = true # Enable Link Time Optimization (LTO) codegen-units = 1 # Reduce the number of code generation units, increasing optimization time but reducing binary size panic = "abort" # Use 'abort' instead of 'unwind' for panic handling strip = "debuginfo" # Remove debug information
Generate a Faster Executable
[profile.release] opt-level = 3 # Optimize for maximum execution speed lto = "fat" # Enable the most aggressive Link Time Optimization codegen-units = 1 # Reduce the number of code generation units, increasing optimization time but improving performance panic = "abort" # Use 'abort' instead of 'unwind' for panic handling
Balance Between Size and Speed
[profile.release] opt-level = "s" # Optimize for size while considering speed lto = "fat" # Enable the most aggressive Link Time Optimization codegen-units = 1 # Reduce the number of code generation units, increasing optimization time but improving performance panic = "abort" # Use 'abort' instead of 'unwind' for panic handling strip = "symbols" # Remove symbol information while retaining necessary debugging info
Explanation of Configurations
opt-level
Description: Specifies the level of compiler optimizations.
Possible values:
0
: No optimization, fastest compilation time.1
: Optimize for faster compilation.2
: Balance between compilation speed and runtime performance (default).3
: Optimize for maximum runtime performance."s"
: Optimize for smaller code size."z"
: Further optimize for code size, more aggressively than"s"
.
Reasoning: Use "z"
to generate the smallest executable; use 3
to generate the fastest executable.
lto
Description: Enables Link Time Optimization (LTO).
Possible values:
false
: Disable LTO (default).true
: Enable LTO."thin"
: Enable Thin LTO."fat"
: Enable the most aggressive LTO.
Reasoning: Enabling LTO reduces binary size and improves runtime performance. "thin"
is a moderate choice, while "fat"
provides the best optimization but increases compilation time.
codegen-units
Description: Controls the number of code generation units.
Default value: Usually 16
. Setting it to 1
enables the highest level of optimization.
Reasoning: Reducing the number of code generation units gives the compiler more information for global optimizations, resulting in a smaller and faster executable. Setting it to 1
maximizes optimization but increases compilation time.
panic
Description: Controls panic behavior.
Possible values:
"unwind"
: Unwind the stack (default)."abort"
: Directly abort the process.
Reasoning: Using "abort"
reduces the executable size and improves performance in some cases since it eliminates the need for stack unwinding information.
strip
Description: Controls which debug and symbol information is removed.
Possible values:
"none"
: Keep all information (default)."debuginfo"
: Remove debug information."symbols"
: Remove symbol tables but retain necessary debug information."all"
: Remove all optional information, including debug and symbol data.
Reasoning: Removing unnecessary debug and symbol information significantly reduces executable size.
Summary
These are the optimization techniques for compiling a Rust project. Have you mastered them?
We are Leapcell, your top choice for hosting Rust projects.
Leapcell is the Next-Gen Serverless Platform for Web Hosting, Async Tasks, and Redis:
Multi-Language Support
- Develop with Node.js, Python, Go, or Rust.
Deploy unlimited projects for free
- pay only for usage — no requests, no charges.
Unbeatable Cost Efficiency
- Pay-as-you-go with no idle charges.
- Example: $25 supports 6.94M requests at a 60ms average response time.
Streamlined Developer Experience
- Intuitive UI for effortless setup.
- Fully automated CI/CD pipelines and GitOps integration.
- Real-time metrics and logging for actionable insights.
Effortless Scalability and High Performance
- Auto-scaling to handle high concurrency with ease.
- Zero operational overhead — just focus on building.
Explore more in the Documentation!
Follow us on X: @LeapcellHQ