O mold é um dos jeitos mais baratos de reduzir o tempo de compilação de projetos Rust no Linux: ele troca o linkador lento do GNU (ld) por um linkador moderno e paralelo, sem alterar o código-fonte. Depois de instalar o pacote do sistema, basta apontar o Cargo com rustflags = ["-C", "link-arg=-fuse-ld=mold"] em .cargo/config.toml. Em builds incrementais de APIs Axum, workers Tokio e CLIs grandes, a etapa de link costuma cair de dezenas de segundos para poucos segundos.
Este guia mostra o que é o mold linker, como instalá-lo, como configurá-lo com Cargo, como medir o ganho real, como compará-lo com LLD e como usá-lo em CI, Docker e monorepos. O mold não resolve monomorfização, macros procedurais pesadas nem download de crates — ele ataca o gargalo específico do link final, que aparece depois que o rustc já emitiu os objetos.
Por que o link importa tanto em Rust
Quando alguém reclama que “Rust é lento para compilar”, costuma misturar três custos diferentes:
- typecheck e borrow check do
rustc; - codegen e monomorfização de genéricos (muito comum com Tokio, Serde e hyper);
- link do executável ou da biblioteca final.
Em um cargo build frio de um serviço novo, as dependências dominam. Em um cargo build quente — o ciclo “salvei o arquivo e quero ver o resultado” — o linkador vira o vilão. O ld.bfd do binutils é correto e estável, mas não foi desenhado para o ritmo de iteração de um monorepo Rust de 2026.
O mold foi criado exatamente para esse cenário: link paralelo, agressivo em performance e com compatibilidade suficiente para o fluxo diário de desenvolvimento. Em times que publicam várias vezes por dia, cada 20–40 segundos economizados no link se multiplica por dezenas de builds locais e de CI.
Se o seu problema ainda é “a primeira compilação demora 8 minutos”, comece pelo guia de como reduzir o tempo de compilação do Rust, por cargo-chef em Docker e por builds Docker otimizados. O mold entra como peça de alto retorno quando o relatório de timings mostra a barra de link grande.
O que é o mold
mold (A Modern Linker) é um linkador ELF de alta performance, mantido de forma independente e disponível nas principais distribuições Linux. A ideia central é simples: o link de um binário grande tem muito trabalho paralelizable — leitura de objetos, resolução de símbolos, relocações, layout de seções — e o mold aproveita múltiplos núcleos de forma agressiva.
Para quem programa em Rust, o ponto prático é:
- o
rustcgera objetos e pede ao driver que invoque o linker do sistema; - com
-C link-arg=-fuse-ld=mold, o GCC/Clang-compatible driver usa o mold em vez doldpadrão; - o binário resultante continua sendo um ELF normal; você não muda a ABI da aplicação só por trocar o linker de desenvolvimento.
Em outras palavras: mold é otimização de developer experience e de CI, não uma reescrita da runtime do Rust.
mold vs LLD vs ld: qual usar?
| Linker | Onde brilha | Limitações típicas | Quando preferir |
|---|---|---|---|
| ld (GNU bfd) | Compatibilidade máxima, default do sistema | Mais lento em projetos grandes | Fallback e ambientes legados |
| LLD (LLVM) | Portabilidade, integração com toolchain LLVM | Em alguns monorepos ainda perde para mold no Linux | macOS/Windows/Linux com foco em homogeneidade LLVM |
| mold | Link muito rápido no Linux | Foco principal em ELF/Linux | Dev local Linux e CI Linux com builds frequentes |
| gold | Histórico como “ld mais rápido” | Projeto menos central hoje | Legado; prefira mold ou LLD em código novo |
Regra prática para times brasileiros rodando Linux em notebooks e em runners de GitHub Actions/Gitea:
- meça com
cargo build --timings; - se o link for relevante, ative mold no alvo Linux;
- mantenha LLD como plano B em imagens mínimas onde mold não esteja disponível;
- não force mold em alvos que ele não cobre bem.
Como instalar o mold
Debian, Ubuntu e derivados
sudo apt update
sudo apt install -y mold
mold --version
Fedora
sudo dnf install -y mold
mold --version
Arch Linux
sudo pacman -S mold
mold --version
Instalação via binário / release
Se a distribuição estiver atrasada, baixe o release oficial do projeto mold e coloque o binário em um diretório do PATH (~/.local/bin ou /usr/local/bin). Em imagens Docker enxutas, instale o pacote da distro da imagem-base ou copie o binário em um stage dedicado.
macOS e Windows
No macOS, o caminho mais comum continua sendo o linker da Apple, com lld ou experimentos de linkers rápidos da plataforma. No Windows, o fluxo MSVC usa link.exe ou lld-link. Por isso, a configuração recomendada neste artigo é escopada ao alvo Linux, para não quebrar builds de colegas em outros sistemas.
Configurar mold no Cargo
A forma mais limpa e versionável é o arquivo .cargo/config.toml do repositório (ou do usuário em ~/.cargo/config.toml).
Configuração por alvo Linux
# .cargo/config.toml
[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
[target.aarch64-unknown-linux-gnu]
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
Essa forma é preferível a exportar RUSTFLAGS globalmente, porque:
- não afeta
cargo testde crates que compilam para outro alvo; - viaja com o repositório;
- deixa explícito para o time que a otimização é do host Linux.
Alternativa com clang como linker driver
Em alguns ambientes, especialmente com toolchains customizadas, usa-se:
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
Só adote isso se o default do cc da máquina não estiver encaminhando -fuse-ld=mold corretamente. Em Ubuntu/Debian recentes com build-essential e mold instalados, a primeira configuração costuma bastar.
Conferir se o mold realmente entrou no build
# Limpe artefatos de link anteriores se quiser um teste limpo do executável
cargo clean -p meu_binario
# Build verboso: procure mold na linha de link
cargo build -vv 2>&1 | rg -i 'mold|fuse-ld'
Se a linha de link mostrar fuse-ld=mold ou invocar mold, a configuração está ativa. Se continuar só com ld/collect2 sem mold, revise o alvo (rustc -vV), o caminho do binário mold e se algum wrapper de CI sobrescreve RUSTFLAGS.
Meça antes e depois
Nunca declare vitória por sensação. Use o relatório nativo do Cargo:
cargo build --timings
Abra target/cargo-timings/cargo-timing.html e observe:
- tempo total;
- tempo da unidade final (o binário ou a cdylib);
- quantos segundos ficam na fase de link em relação ao codegen.
Compare três cenários:
- build frio (
cargo clean+ build) — mold ajuda, mas dependências ainda dominam; - build incremental de código (mude uma linha em
src/main.rs) — aqui mold brilha; - build após mudança de
Cargo.toml/Cargo.lock— muita recompilação de crates; mold ajuda no final, mas não apaga o custo dorustc.
Para números repetíveis:
hyperfine --warmup 1 \
'cargo build -q' \
'cargo build -q --release'
Lembre: release e dev têm perfis diferentes. O mold acelera o link nos dois, mas o codegen de --release continua bem mais caro.
mold em workspaces e monorepos
Em Cargo workspaces, o ganho se multiplica porque cada binário (api, worker, cli, migrate) paga um link próprio. Um monorepo com quatro binaries pode invocar o linker quatro vezes no mesmo cargo build --workspace.
Boas práticas:
- coloque a config de mold na raiz do workspace, não em cada crate;
- evite misturar
RUSTFLAGSdiferentes entre crates do mesmo build; - se algum membro precisa de flags especiais (por exemplo,
cdylibcom version script), isole essas flags no alvo/pacote e não desligue o mold para o resto do monorepo sem medir; - combine com cargo-nextest na CI: testes mais rápidos + link mais rápido = feedback bem mais curto.
mold na CI
Em runners Linux efêmeros, o mold reduz o tempo do job depois que as dependências já estão cacheadas. A ordem de alavancas continua sendo:
- cache de
~/.cargo/registrye git; - cache de compilação (
sccacheou cache detargetcom chave correta); - mold para o link;
- paralelismo de testes com nextest;
- cargo-chef quando o build roda dentro de Docker.
Exemplo mínimo em um job Debian/Ubuntu:
- name: Install mold
run: sudo apt-get update && sudo apt-get install -y mold
- name: Configure Cargo to use mold
run: |
mkdir -p .cargo
cat >> .cargo/config.toml <<'EOF'
[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
EOF
- name: Build
run: cargo build --locked --all-targets
Se o repositório já versiona .cargo/config.toml com mold, o step de “Configure Cargo” fica desnecessário — o que é o ideal.
Armadilha de RUSTFLAGS na CI
Pipelines que fazem:
export RUSTFLAGS="-D warnings"
podem sobrescrever silenciosamente as flags do .cargo/config.toml dependendo de como as flags são mescladas no ambiente. Prefira:
export RUSTFLAGS="${RUSTFLAGS:-} -D warnings"
ou configure lints no Cargo.toml/[lints] e deixe o mold no config do alvo. Sempre valide com cargo build -vv no job quando o tempo de link “não mudou”.
mold em Docker
Dentro de uma imagem de build:
FROM rust:1-bookworm AS builder
RUN apt-get update \
&& apt-get install -y --no-install-recommends mold \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C link-arg=-fuse-ld=mold"
# ... COPY manifests, cargo chef cook, COPY src, cargo build --release
Ou grave o .cargo/config.toml no contexto do build. Em multi-stage, o mold precisa existir apenas no stage de compilação; a imagem final de runtime não carrega o linker.
Combine com:
- cargo-chef para cache de dependências;
- Docker otimizado para Rust para stages mínimos;
- cache BuildKit montado em
/usr/local/cargo/registryquando fizer sentido.
O mold não substitui essas peças: ele só encurta o RUN cargo build --release quando o linker seria o freio de mão.
O que o mold não resolve
Seja honesto com o time — mold não é milagre:
- não reduz monomorfização de genéricos;
- não acelera macros procedurais pesadas (
serde,prost,async-traitem excesso); - não evita baixar crates do crates.io;
- não substitui
sccacheentre máquinas; - não corrige features desnecessárias em dependências;
- não melhora tempo de teste por si só (a não ser pelo relink de binários de integração).
Para o restante do pipeline de performance de build e de runtime, use o mapa:
| Sintoma | Ferramenta / guia |
|---|---|
| Link lento no Linux | mold (este guia) |
| Rebuild Docker recompila deps | cargo-chef |
| Mesmas crates recompilam em CI | sccache no guia de tempo de compilação |
| Suíte de testes lenta | cargo-nextest |
| Binário grande / features demais | Cargo + corte de features |
| CPU em produção, não no build | profiling em produção |
Checklist de adoção em um projeto real
-
mold --versionfunciona no host ou na imagem de build; -
.cargo/config.tomldefine mold só nos alvos Linux relevantes; -
cargo build -vvmostrafuse-ld=mold; -
cargo build --timingsfoi comparado antes/depois em build incremental; - CI instala mold ou usa imagem que já o contém;
-
RUSTFLAGSda CI não apaga a config do mold; - macOS/Windows do time não quebram por config global agressiva;
- Docker multi-stage instala mold só no builder;
- documentação interna do time menciona a dependência de sistema;
- release engineering e assinatura de binários continuam iguais (guia de release).
mold e carreira: por que isso aparece em entrevista
Em processos seletivos de backend, plataforma e DevOps, “como você encurta o ciclo de feedback de um monorepo Rust?” é uma pergunta cada vez mais comum. Saber explicar a diferença entre compilar e linkar, citar cargo build --timings, mold/LLD, sccache e cargo-chef mostra maturidade de engenharia — não só de sintaxe da linguagem.
Se você está montando portfólio para o mercado brasileiro, combine esse tipo de otimização prática com projetos publicáveis e com acompanhamento de vagas Rust e empresas que usam Rust. Builds rápidos não substituem ownership e async, mas são o tipo de detalhe que separa quem só “fez o tutorial” de quem já sofreu com CI de verdade.
Conclusão
O mold linker é uma das otimizações de melhor relação esforço/benefício para quem desenvolve Rust no Linux em 2026. A instalação é trivial, a configuração cabe em poucas linhas de .cargo/config.toml e o impacto aparece exatamente no ciclo que mais dói: o build incremental do dia a dia e os jobs de CI que já têm cache de dependências.
Não use mold como desculpa para ignorar features inchadas, Docker sem multi-stage ou testes seriais. Use-o como peça de um sistema: meça com timings, acelere o link com mold, estabilize deps com cargo-chef, reutilize compilação com sccache e paralelize testes com nextest. Esse combo é o que times sérios de Rust colocam de pé quando o produto cresce e o cargo build deixa de ser detalhe.
Perguntas frequentes
O que é o mold linker?
mold é um linkador moderno focado em velocidade, especialmente eficaz em binários ELF no Linux. Em projetos Rust, ele substitui o ld lento na etapa final do cargo build.
Como usar mold com Cargo?
Instale o mold no sistema e adicione ao .cargo/config.toml:
[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
Valide com cargo build -vv e meça com cargo build --timings.
mold funciona no macOS?
O foco do mold é Linux/ELF. No macOS, mantenha o linker da plataforma ou LLD e restrinja a config de mold aos alvos *-unknown-linux-gnu.
mold é melhor que LLD?
Em muitos monorepos Linux, sim para tempo de link. LLD ainda é excelente e mais “universal” no ecossistema LLVM. A decisão correta é medir no seu projeto.
mold substitui sccache e cargo-chef?
Não. mold acelera o link; sccache cacheia compilação; cargo-chef cacheia dependências em layers Docker. Combine as três quando cada uma atacar um gargalo real.