Por que tempo de compilação importa tanto em Rust
Nenhuma linguagem transforma tanto tempo de compilação em segurança. Antes de produzir um binário, o compilador do Rust faz inferência de tipos, monomorfização de genéricos, expansão de macros procedurais e a famosa análise de borrow em praticamente todo o programa. É o que entrega a combinação rara de zero garbage collector, concorrência sem data races e ergonomia — mas é também o motivo de o primeiro cargo build de um projeto com Tokio, Axum e meia dúzia de crates demorar tanto.
O custo não é só de paciência. Em times reais, builds lentos travam CI, atrasam code review e reduzem a frequência de iteração. Se você busca vagas de Rust ou já trabalha com a linguagem, otimizar o tempo de compilação é uma habilidade de engenharia tão valorizada quanto escrever código idiomático: ela aparece direto em CI/CD com Rust, em builds Docker otimizados e na engenharia de release de binários. Este guia é um checklist prático para 2026.
Diagnóstico: meça antes de otimizar
Antes de mudar qualquer coisa, meça. Onde o tempo está indo? Em dependências? No link final? Em uma macro procedural pesada?
# Gera um relatório HTML com o tempo de cada crate e a paralelização real
cargo build --timings
# Compare alterações de forma confiável com hyperfine
hyperfine --warmup 3 'cargo build' 'cargo build --release'
O cargo build --timings abre target/cargo-timings/cargo-timing.html no navegador e mostra qual crate bloqueou qual, além de quanto tempo foi gasto em série versus paralelo. Em paralelo, ferramentas como cargo bloat e cargo tree ajudam a entender o tamanho do problema de dependências — muitas vezes o culpado é uma única crate que puxa centenas de transições.
As otimizações de maior retorno no dia a dia
1. Use um linkador rápido (mold ou LLD)
O link final é, na maioria dos projetos médios, o maior gargalo de builds incrementais. O ld do GNU é lento; mold e lld cortam esse tempo drasticamente. Configure uma vez no repositório:
# .cargo/config.toml
[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
No macOS, o linkador padrão (ld64) já é razoável, mas vale conferir o ld64.s/ld-prime mais recente do toolchain. No Windows, o lld-link costuma bater o link.exe da Microsoft em builds grandes.
2. Reduza informação de debug no perfil de desenvolvimento
Debug info é útil, mas é caro de gerar e de linkar. Para iteração rápida, use níveis mais leves:
# Cargo.toml
[profile.dev]
debug = "line-tables-only" # suficiente para backtraces, bem mais rápido
split-debuginfo = "unpacked" # estável desde 1.65; acelera muito no Linux/macOS
[profile.dev.package."*"]
opt-level = 2 # compila dependências otimizadas (mais lento p/ compilar? não — vê nota)
A opção split-debuginfo = "unpacked" é uma das melhorias mais subutilizadas: ela separa a informação de debug em arquivos e reduz drasticamente o tempo de link incremental. O opt-level = 2 nas dependências faz a compilação delas demorar um pouco mais na primeira vez, mas acelera muito a execução de testes — uma troca que costuma valer a pena.
3. Aumente os codegen-units para dev, mantenha 1 no release
[profile.dev]
codegen-units = 256 # mais paralelismo na geração de código = build mais rápido
[profile.release]
codegen-units = 1 # menos paralelismo, mas melhor otimização no binário final
Mais codegen-units acelera a compilação à custa de otimizações cross-unit; o valor certo para dev é alto, e para release é 1.
Cache entre projetos e máquinas: sccache
O sccache é um cache de compilador compartilhado. Ele evita recompilar crates idênticas entre projetos, branches e máquinas de CI:
cargo install sccache
# Configure no ambiente (ou no .cargo/config.toml)
export RUSTC_WRAPPER=sccache
Em pipelines de CI, armazenar o cache do sccache (no S3, GCS ou local) costuma cortar minutos de builds repetidos. É uma das alavancas de maior retorno em monorepos Rust e em empresas que usam Rust com dezenas de serviços.
Cranelift: iteração local mais rápida (nightly)
O backend Cranelift gera código de máquina muito mais depressa que o LLVM, com otimizações mais modestas. É ideal para o ciclo interno — rodar testes, validar lógica — e pode ser habilitado por perfil em nightly:
rustup toolchain install nightly
rustup component add rustc-codegen-cranelift-preview --toolchain nightly
# Use só no perfil de desenvolvimento
RUSTFLAGS="-Zcodegen-backend=cranelift" cargo +nightly build
O ganho é maior em projetos com bastante código de aplicação (menos em bibliotecas que passam o tempo todo em dependências). Importante: o binário de produção continua sendo gerado pelo LLVM; o Cranelift é uma ferramenta de produtividade, não de entrega final.
Dependências e features: corte o que não usa
A forma mais eficaz de acelerar um build grande é compilar menos código. Algumas práticas que funcionam em 2026:
- Audite features com
cargo tree -e features: muitas crates ativam recursos (serde,tokio,tracing) que você não usa. - Use
--no-default-featuresquando possível e ative só o necessário:chrono = { version = "0.4", default-features = false, features = ["clock"] }. - Evite macros procedurais pesadas em hot paths de compilação; elas rodam em cada build e não são cacheadas tão bem quanto código normal.
- Monomorfização excessiva: genéricos que são instanciados para dezenas de tipos incham o binário e o tempo de build. Em casos extremos, funções internas não-genéricas (
fnem vez deT) reduzem a explosão de código.
CI e Docker: cache estruturado
Em CI/CD, o segredo é cachear ~/.cargo/registry, target (quando viável) e o sccache. Em imagens Docker, separe o Cargo.toml/Cargo.lock do código-fonte para que a camada de dependências só seja reconstruída quando realmente mudam — tema detalhado no nosso guia de builds Docker otimizados. Para a execução de testes, o cargo-nextest roda suítes em paralelo de forma muito mais eficiente que o cargo test padrão, conforme discutimos no guia de estratégias de testes.
Conclusão
Não existe um único botão que torna o Rust rápido para compilar, mas a combinação de diagnóstico com cargo build --timings, linkador moderno (mold/lld), split-debuginfo, sccache, Cranelift para dev e corte agressivo de features costuma transformar um build de minutos em segundos na iteração diária. O binário de produção continua ganhando as otimizações pesadas do LLVM; o que mudamos é o tempo que você espera entre salvar o arquivo e ver o resultado.
Comece medindo, aplique o linkador rápido e o split-debuginfo (são ganhos quase de graça), e reserve o Cranelift e o corte de dependências para projetos em que o tempo de build já é um problema real. Sua produtividade — e a do seu time — vai sentir a diferença.
Leia também:
- Profiling e Performance em Produção
- CI/CD com Rust
- Builds Docker Otimizados
- Engenharia de Release de Binários
- Estratégias de Testes em Rust
- Cargo — Gerenciador do Ecossistema
Veja também nossos sites parceiros:
- Go Brasil — Go compila em segundos; entenda quando a velocidade de build pesa na escolha entre as linguagens
- Zig Brasil — compilação rápida por design, com cache de builds que influenciou o ecossistema de sistemas
- Python Brasil Dev — sem etapa de compilação nativa, mas com o trade-off oposto de performance em tempo de execução