Aprende Rust · 5 min

Reducir el tamaño del binario en Rust

Técnicas ordenadas por impacto y facilidad para que tu binario pese menos, con el perfil de Cargo exacto.

Un "hola mundo" en Rust pesa más de lo que esperarías. No es desperdicio: el binario incluye por defecto parte de la biblioteca estándar, los símbolos de depuración, la maquinaria para desenrollar la pila cuando hay un panic y el formateo de mensajes. Nada de eso aparece en tu código, pero viaja dentro. La buena noticia es que casi todo se puede recortar desde Cargo.toml.

Técnicas, de la más fácil a la más agresiva

TécnicaAjusteCosto
Compilar en releasecargo build --releaseNinguno; es el punto de partida.
Quitar símbolosstrip = truePierdes símbolos para depurar.
Optimizar por tamañoopt-level = "z" (o "s")Puede ser más lento.
LTOlto = trueCompila más lento.
Una unidad de códigocodegen-units = 1Compila más lento.
Abortar en panicpanic = "abort"Sin desenrollado de pila.
Casos extremosno_std, build-std (nightly)Complejidad alta.

El perfil recomendado

Reúne los ajustes principales en el perfil de release. Este bloque es un buen punto medio:

[profile.release]
opt-level = "z"     # optimiza por tamaño ("s" a veces resulta menor)
lto = true          # optimización de enlace entre crates
codegen-units = 1   # menos paralelismo, mejor optimización
panic = "abort"     # sin maquinaria de desenrollado
strip = true        # elimina símbolos

Cada línea hace algo concreto:

  • opt-level = "z" le pide al compilador que priorice tamaño sobre velocidad. "s" es un punto intermedio y, en algunos casos, produce un binario aún menor; conviene probar ambos.
  • strip = true elimina los símbolos (equivale a "symbols"). Es de los cambios con mejor relación esfuerzo/resultado.
  • lto = true activa la optimización de enlace sobre todo el grafo de dependencias, lo que permite descartar código muerto.
  • codegen-units = 1 sacrifica paralelismo en la compilación a cambio de una optimización más completa.
  • panic = "abort" quita el código que desenreda la pila ante un panic; el proceso simplemente termina.

Quitar peso de las dependencias

A veces el problema no es tu código, sino lo que arrastras. Dos herramientas ayudan a verlo:

cargo install cargo-bloat
cargo bloat --release --crates   # qué crates ocupan más
cargo tree                        # el árbol de dependencias

cargo-bloat muestra qué funciones y qué crates ocupan más espacio; cargo tree revela qué depende de qué. Con eso puedes decidir si una dependencia pesada tiene un reemplazo más liviano o si puedes desactivar alguna de sus features. Ambas aparecen en la caja de herramientas.

Casos extremos

Cuando cada kilobyte cuenta, hay más que se puede hacer, a costa de complejidad:

  • #![no_std] renuncia a la biblioteca estándar y deja solo core. Es el camino de los sistemas embebidos.
  • build-std (solo en nightly) recompila la propia biblioteca estándar con tus opciones de optimización, en lugar de usar la precompilada.

Estos caminos no son para la mayoría de proyectos. Entra en ellos solo si mediste y lo necesitas.

Qué viaja dentro de un binario de releaseTu códigoBiblioteca estándarSímbolosDesenrolladode pánicoFormatode pánico*Punteado: lo recortable.Símbolos → strip = true · Desenrollado → panic = "abort"
Lo que contiene un binario y qué ajuste recorta cada parte; esquema, no a escala. *El formato de los mensajes de pánico solo se elimina del todo en el caso extremo (panic=immediate-abort, nightly). En ese extremo, min-sized-rust lleva un binario de unos 2 MB a cerca de 8 KB.

Qué recordar

Empieza por lo barato: strip y el perfil de release bien configurado te dan la mayor parte del resultado con poco riesgo. Mide el tamaño antes y después, y mide también el rendimiento si la velocidad te importa. Reserva no_std y build-std para cuando de verdad persigas el mínimo, no por costumbre.

Fuentes

  1. GitHub - johnthagen/min-sized-rust: How to minimize Rust binary sizemin-sized-rust, 2026
  2. Profiles - The Cargo BookThe Cargo Book

Construye mejor software.

Seguridad, eficiencia y oficio, con fuentes.