How to Mix Gentoo Binary Packages With Source Builds Without Losing Control
For most of Gentoo’s history, using binary packages meant setting up your own build server. That changed at the end of 2023, when the project began publishing official binary packages for its main architectures, signed with the same key as its installation stages. The announcement was easy to misread as “Gentoo is becoming a binary distribution”. It isn’t. Portage has always been able to install prebuilt packages, and the new binary host simply gives every user a ready-made source of them.
The interesting part is how Portage decides, package by package, whether to download a binary or compile from source. That decision depends on your USE flags, your profile, your patches, the state of the ebuild repository and a handful of emerge options whose defaults are not obvious. Get them right and LibreOffice, a browser and a full desktop arrive in minutes, while the packages you actually care about are still built with your own configuration. Get them wrong and Portage quietly compiles everything anyway, or installs binaries you did not expect.
This manual explains how the mechanism works, how to configure it, why binaries are sometimes ignored, and how to keep fine-grained control over what is built locally. The option names and defaults below come from the current Portage documentation, the emerge(1), make.conf(5) and portage(5) manual pages, as of October 2026.

What the official binary host provides
When Gentoo announced the service in December 2023, it described two levels of coverage. The amd64 and arm64 architectures received extensive package sets, more than 20 GB at launch, including large desktop components such as LibreOffice, KDE Plasma and GNOME, and these are rebuilt daily for the stable branch. Other architectures received a smaller set covering the core system and toolchain, updated weekly alongside the installation stages.
The packages are built for a small number of reference profiles, including desktop profiles for GNOME and KDE Plasma, with each profile’s default USE flags. They are compiled with deliberately conservative compiler settings. For amd64 the announcement listed -march=x86-64 -mtune=generic -O2 -pipe, which runs on any 64-bit x86 processor. In February 2024 Gentoo added a second amd64 package set built for the x86-64-v3 microarchitecture level, for processors that support AVX2 and related extensions.
Two limits matter. Binaries are tied to a profile version: packages built for one profile generation are not intended for systems on another. And the original announcement covered the stable branch. Users who run testing keywords on many packages will find more of them falling back to source builds. Because coverage and paths change over time, the current binary host documentation on the Gentoo wiki is the reference for the exact repository location for your architecture and profile.
The three moving parts
Using binary packages involves three separate configuration layers.
The repository definition in /etc/portage/binrepos.conf/ tells Portage where binary packages come from. Recent stage tarballs already contain a file for the official binary host, typically named gentoobinhost.conf.
Feature flags in /etc/portage/make.conf control whether Portage uses remote binaries by default and how strictly it checks signatures.
Emerge options, set on the command line or in EMERGE_DEFAULT_OPTS, decide how binaries are matched against your configuration and which packages are allowed or excluded.
Defining the repository
A binary repository is defined in an INI-style file, one section per repository:
[gentoobinhost]
priority = 9999
sync-uri = <binary host address for your architecture and profile>Replace the placeholder with the address given in the official documentation for your architecture, profile version and, on amd64, the x86-64 or x86-64-v3 variant. If you installed from a recent stage, check the existing file before creating another.
The portage(5) manual lists the supported attributes:
html
<table>
<thead>
<tr>
<th>Attribute</th>
<th>Effect</th>
</tr>
</thead>
<tbody>
<tr>
<td>sync-uri</td>
<td>Address of the binary package repository used by emerge --getbinpkg</td>
</tr>
<tr>
<td>priority</td>
<td>When the same package version exists in several binary repositories, higher priority wins</td>
</tr>
<tr>
<td>verify-signature</td>
<td>Whether OpenPGP signatures are checked for packages from this repository; defaults to true</td>
</tr>
<tr>
<td>location</td>
<td>Local cache for downloaded packages; with current Portage the default is /var/cache/binhost/ followed by the repository name</td>
</tr>
<tr>
<td>getbinpkg-include / getbinpkg-exclude</td>
<td>Experimental per-repository lists of packages to fetch or not fetch</td>
</tr>
<tr>
<td>openpgp-key-package</td>
<td>Package containing the signing keys; Portage notifies you if it has an update after syncing</td>
</tr>
<tr>
<td>frozen (DEFAULT section only)</td>
<td>Use the cached remote index without refreshing it, for reproducible dependency calculations</td>
</tr>
</tbody>
</table>The older PORTAGE_BINHOST variable in make.conf still works, but the documentation describes binrepos.conf as its replacement and marks the old variable as deprecated in the context of the getbinpkg feature.
Turning on binary downloads
There are two ways to tell Portage to use the remote repository. You can pass --getbinpkg (short form -g) on each emerge command, or enable it permanently:
FEATURES="${FEATURES} getbinpkg"With the feature enabled, every emerge consults the binary repository when building the dependency graph. According to make.conf(5), this feature cannot be set per package through package.env. Per-package control is done with the include and exclude options described later.
Signatures and the trust anchor
Gentoo’s official binary packages use the GPKG format, which supports embedded OpenPGP signatures. The older XPAK format cannot carry signatures. GPKG is now Portage’s default format for packages you build yourself as well: the global default is BINPKG_FORMAT="gpkg".
Signature checking for remote packages is on by default, through the verify-signature = true default in binrepos.conf. To make Portage reject any binary package without a valid signature, including local ones, enable:
FEATURES="${FEATURES} binpkg-request-signature"The make.conf(5) page notes that this feature, when enabled, takes precedence over the per-repository setting.
Verification needs a local trust anchor containing Gentoo’s release keys. The tool getuto sets this up. If verification fails on a fresh system, running getuto as root is the documented first step.
How Portage decides between binary and source
With a repository configured and getbinpkg enabled, Portage does not simply download whatever binary exists. For each package in the dependency graph, it compares the available binary with what the current configuration would build. If they differ in a way Portage considers significant, the binary is ignored and the package is compiled from source.
Three emerge options control this comparison. Their defaults are what make mixed setups safe.
--binpkg-respect-use makes emerge ignore binary packages whose USE flags do not match the current configuration. It is enabled automatically unless --usepkgonly or --getbinpkgonly is used.
--binpkg-changed-deps ignores binary packages whose corresponding ebuild’s dependencies have changed since the binary was built. It is also enabled automatically except in binary-only modes.
--binpkg-respect-user-patches ignores binary packages whose user patches do not match your configuration in /etc/portage/patches/. According to the manual, it is enabled by default even in binary-only mode, so a binary never silently reverts a patch you apply.
The practical result is that a package is installed from a binary only when the binary was built with exactly the USE flags your configuration requests, against current dependencies, and with the same user patches. Everything else is compiled.
Why many binaries get ignored
This is where most surprises come from, because several common configuration habits change USE flags without looking like USE changes.
CPU_FLAGS_X86. Many Gentoo guides recommend running cpuid2cpuflags and setting CPU_FLAGS_X86 in make.conf to describe your processor’s instruction-set extensions. CPU_FLAGS_X86 is a USE_EXPAND variable: each value becomes a USE flag, such as cpu_flags_x86_avx2, on every package that declares it. If your values differ from those used on the binary host, every package that uses those flags has a USE mismatch, and Portage builds it from source.
Other USE_EXPAND variables. The same applies to VIDEO_CARDS, L10N, PYTHON_TARGETS, LLVM_SLOT and similar variables. A global change to any of them can exclude a large number of binaries at once.
A different profile. Binaries are built against specific profiles. On a profile whose default USE flags differ significantly, such as a minimal server profile while the binaries come from a desktop profile, many packages will not match.
Testing keywords. Packages accepted with ~amd64 or ~arm64 may be newer than the versions available as binaries, and then there is simply no matching binary.
User patches. Any package with patches in /etc/portage/patches/ will be built locally.
Compiler flags are a notable exception. Portage does not compare your CFLAGS with those used to build a binary. A binary built with generic flags is installed even if your make.conf specifies -march=native. If you want a package compiled with your own flags, you must exclude it from binary installation explicitly.
Seeing what Portage will do
Before a large update, it is worth checking which packages will come from binaries and which will be compiled:
emerge --pretend --verbose --update --deep --newuse --getbinpkg @worldIn the output, packages that will be installed from binary packages are marked as binary at the start of the line, while packages to be compiled are shown as normal ebuild merges. If you expected a binary and see a source build, compare the USE flags shown in the verbose output with the defaults of the profile used for the binaries.
The usual full update command with binaries enabled is the same as for source updates, with --getbinpkg added or the getbinpkg feature enabled:
emerge --ask --verbose --update --deep --newuse --getbinpkg @worldKeeping control of what is built locally
The strength of the mixed approach is choosing which packages to compile yourself. Portage offers several ways to do this, depending on whether you think in terms of exceptions or of a whitelist.
Compile a few packages, take binaries for the rest
To always compile certain packages, for example ones where you want your own compiler flags or patches, use --usepkg-exclude. It excludes the listed packages from binary installation entirely, local and remote, when -g is used:
EMERGE_DEFAULT_OPTS="${EMERGE_DEFAULT_OPTS} --usepkg-exclude 'media-video/ffmpeg sys-kernel/gentoo-sources'"The narrower --getbinpkg-exclude only prevents remote binaries from being fetched. Local binaries in your own package directory can still be used.

Take binaries only for the heavy packages
The opposite approach suits users who want to keep compiling most of the system but avoid the longest builds. --getbinpkg-include limits remote fetching to the listed packages:
EMERGE_DEFAULT_OPTS="${EMERGE_DEFAULT_OPTS} --getbinpkg-include 'www-client/firefox app-office/libreoffice dev-lang/rust'"Everything not listed is compiled from source, while the listed packages are fetched as binaries when their configuration matches. The same lists can be set per repository with the experimental getbinpkg-include and getbinpkg-exclude attributes in binrepos.conf.
Binary-only installation
For emergencies, such as a broken toolchain or a very slow machine that needs a working system quickly, --getbinpkgonly (-G) or --usepkgonly (-K) restricts emerge to binaries. These modes behave differently from the default.
html
<table>
<thead>
<tr>
<th>Option</th>
<th>Short form</th>
<th>Behaviour</th>
</tr>
</thead>
<tbody>
<tr>
<td>--usepkg</td>
<td>-k</td>
<td>Use local binary packages from PKGDIR when available, otherwise compile; implies --with-bdeps=n unless overridden</td>
</tr>
<tr>
<td>--getbinpkg</td>
<td>-g</td>
<td>Also consult remote binary repositories; implies -k</td>
</tr>
<tr>
<td>--usepkgonly</td>
<td>-K</td>
<td>Use only binary packages; abort if any are missing; ignores ebuild repositories and masking for dependency calculation; implies --binpkg-respect-use=n</td>
</tr>
<tr>
<td>--getbinpkgonly</td>
<td>-G</td>
<td>Like -g but binary-only, preferring remote binaries over local ones when they differ; implies --usepkgonly and --binpkg-respect-use=n</td>
</tr>
</tbody>
</table>The binary-only modes turn off --binpkg-respect-use, so they install binaries even if their USE flags differ from your configuration. That is the point of these modes, but it means your system may afterwards contain packages built with flags you did not choose. Running a normal update with --newuse later lets Portage rebuild those packages to match your configuration.
--usepkg and --usepkgonly also imply --with-bdeps=n, so build-time dependencies are not pulled in unless you request them with --with-bdeps=y. This is usually desirable for binary installations, but it can surprise users who later compile packages that need those dependencies.
Building and sharing your own binary packages
The official binary host covers common configurations. Users with several machines that share a configuration often run their own binary repository as well, built with their USE flags and compiler settings.
Enabling FEATURES="buildpkg" on the build machine makes Portage create a binary package for every package it compiles, alongside installing it. The packages go into PKGDIR, which defaults to /var/cache/binpkgs on current systems. The quickpkg tool creates binary packages from already installed software, which is useful for building a cache from an existing system.
To share packages with other machines, serve the PKGDIR directory over HTTP or HTTPS and add a binrepos.conf entry on the client machines pointing to it. Use a higher priority than the official binary host if you want your own builds preferred when both have the same version.
A shared repository must use compiler flags that every client can run. A build machine using -march=native can produce binaries that crash on an older client. For a fleet with mixed hardware, a common target such as -march=x86-64-v3 for machines that support it, or the generic baseline otherwise, is safer.
To sign your own packages, enable FEATURES="binpkg-signing" and configure a signing key. Clients then need your public key in their trust anchor if they verify signatures. For a private binary host on a trusted local network, some users disable verification for that repository only with verify-signature = false. This trades security for convenience and is a deliberate choice, not a default.
Binary package directories grow quickly. The eclean-pkg tool from app-portage/gentoolkit removes outdated packages. After deleting packages manually, emaint --fix binhost rebuilds the package index.
Troubleshooting the common failures
Everything is compiled even though binaries exist. Check USE flags first. The most common cause is a global CPU_FLAGS_X86, VIDEO_CARDS or L10N setting that differs from the binary host’s profile. Compare the verbose output of emerge --pretend with the profile used for the binaries.
Signature verification fails. Run getuto to initialise or update the trust anchor. If the error mentions an unsigned package, check whether it came from an XPAK repository or a local package built without signing while binpkg-request-signature is enabled.
A binary was installed with unexpected USE flags. This usually follows a binary-only run with -K or -G. A normal update with --newuse rebuilds affected packages to match your configuration.
Dependency calculations differ between runs. The remote package index changes as the binary host updates. Setting frozen = yes in the DEFAULT section of binrepos.conf uses the cached index, which gives reproducible results while you work through a complicated update. The manual advises using it only temporarily.
Binaries from the wrong profile generation. After a profile migration, update the sync-uri to the repository matching your new profile before using binaries again.
A sensible default setup
For most desktop users, a balanced configuration looks like this:
Use the official binary host for your architecture and profile, with signature verification left on.
Enable binaries with
FEATURES="getbinpkg", or pass-gwhen you want them.Keep global USE_EXPAND changes deliberate, knowing that each one can exclude many binaries.
Exclude the few packages you want compiled with your own flags or patches, using
--usepkg-exclude.Check the plan with
--pretendbefore large updates, so you know how much will be compiled.
Mixing binaries and source builds does not dilute what makes Gentoo different. Portage still computes the full dependency graph from your configuration, still respects your USE flags by default, and still builds any package that does not match. The binary host only removes the time spent compiling packages you would have built with default settings anyway, leaving your attention, and your processor, for the ones where your choices make a difference.