The Rebuild Algorithm
Slow and Steady Wins the Race
The Fedora ELN SIG maintains a tool called ELNBuildSync (or EBS) which is responsible for monitoring traffic on the Fedora Messaging Bus and listening for Koji tagging events. When a package is tagged into Rawhide (meaning it has passed Fedora QA Gating and is headed to the official repositories), EBS checks whether it’s on the list of packages targeted for Fedora ELN or ELN Extras and enqueues it for the next batch of builds.
A batch begins when there are one or more enqueued builds and at least sixty wallclock seconds have passed since a build has been enqueued. This allows EBS to capture events such as a complete side-tag being merged into Rawhide at once; it will always rebuild those together in a batch. Once a batch begins, EBS stops accepting messages from the Fedora Messaging Bus. The messages remain enqueued and awaiting processing. When the current batch is complete, EBS will resume accepting messages and a new batch will begin.
The first thing that is done when processing a batch is to create a new side-tag derived from the ELN buildroot. Into the new target associated with this side-tag (which will be referred to as the “build tag” from now on), EBS will tag most1 of the Rawhide builds. It will then wait until Koji has regenerated the buildroot for the batch tag before triggering the rebuild of the batched packages. This strategy avoids most of the ordering issues (particularly bootstrap loops) inherent in rebuilding a side-tag, because we can rely on the Rawhide builds having already succeeded.
Once the preparations are complete, we divide the batch up into one or more “batch slices”. The EBS configuration file contains information about certain packages that must be built and added to the buildroot before or after other packages. (Most packages will be part of the same primary slice, but some packages must be built early, such as llvm). EBS triggers all of the builds for a batch slice in the side-tag concurrently, sourcing the content from the git commit that was used to build the triggering Rawhide build. This is to ensure we are building the same content, in case dist-git has received subsequent changes. EBS monitors these builds for completion. Internally, we call these “rebuild attempts”.
Once all of the tasks in a rebuild attempt have completed (successfully or not), EBS will trigger another rebuild attempt of the failures. While a heavyweight solution, this helps us avoid failures due to infrastructure outages, flaky tests and bootstrapping issues not covered by the Rawhide build tagging. Rebuild attempts will continue to be initiated until the same number of failures occurs twice in a row. At that point, we assume they are legitimate build issues and we continue on.
Once all of the rebuild attempts have concluded, EBS moves on to the next slice in order until they have all completed, at which point, the next phase of operation begins: errata creation.
In earlier versions of ELNBuildSync, EBS would now tag all successful builds into the eln-updates-candidate tag and then remove the build tag. The effect of this would be to trigger Bodhi to generate an erratum for each individual package in the batch.
In modern versions of ELNBuildSync, it will now create a second2 side-tag (call it the “errata tag”). EBS then tags all of the successful package builds from the batch into this new errata tag. This ensures that the tag contains only the new ELN builds and none of the Rawhide packages that were tagged into the build tag. From there, EBS talks to Bodhi via its public API and requests that a single Bodhi update erratum be created for all of the packages in this errata tag. This is done to reduce the load on Fedora QA, as the infrastructure there is far better equipped to deal with a single update of a few hundred packages than it is with a few hundred separate updates.
At this point, the batch is complete and EBS moves on to preparing another batch, if there are packages waiting.
History
In its first incarnation, ELNBuildSync (at the time known as DistroBuildSync) was very simplistic. It listened for tag events on Rawhide, checked them against its list and then triggered a build in the ELN target. Very quickly, the ELN SIG realized that this had significant limitations, particularly in the case of packages building in side-tags (which was becoming more common as the era of on-demand side-tags began). One of the main benefits of side-tags is the ability to rebuild packages that depend on one another in the proper order; this was lost in the BuildSync process and many times builds were happening out of order, resulting in packages with the same NVR as Rawhide but incorrectly built against older versions of their dependencies.
Initially, the ELN SIG tried to design a way to exactly mirror the build process in the side-tags, but that resulted in its own new set of problems. First of all, it would be very slow; the only way to guarantee that side-tags are built against the same version of their dependencies as the Rawhide version would be to perform all of those builds serially. Secondly, even determining the order of operations in a side-tag after it already happened turned out to be prohibitively difficult.
Instead, the ELN SIG recognized that the Fedora Rawhide packagers had already done the hardest part. Instead of trying to replicate their work in an overly-complicated manner, instead the tool would just take advantage of the existing builds. Now, prior to triggering a build for ELN, the tool would first tag the current Rawhide builds into ELN and wait for them to be added to the Koji buildroot. This solved about 90% of the problems in a generic manner without engineering an excessively complicated side-tag approach. Naturally, it wasn’t a perfect solution, but it got a lot further. (See below for “Why are some package not tagged into the batch side-tag?” for more details.
A more recent modification to this strategy came about as CentOS Stream 10 started to come into the picture. With the intent to bootstrap CS 10 initially from ELN, tagging Rawhide packages to the ELN tag suddenly became a problem, as CS 10 needs to use that tag event as its trigger. The solution here was not to tag Rawhide builds into Fedora ELN directly, but instead to create a new ELN side-tag target where we could tag them, build the ELN packages there and then tag the successful builds into ELN. As a result, CS 10 builds were only triggered on ELN successes.
In late 2025, Fedora QA came to the ELN SIG and requested that we find some way to reduce the number of individual errata we were generating, as when they attempted to turn on automated testing for ELN, the result was an overload and significant queuing around mass-rebuilds and other large batches. When it got to the point that the Standard Operating Procedure for mass-rebuilds included disabling all the tests for ELN, it became clear that changes were needed and EBS was modified to start directly requesting errata for all the builds in the batch instead.
Frequently Asked Questions
Why does it sometimes take a long time for my package to be rebuilt?
Not all batches are created equal. Sometimes, there will be an ongoing batch with one or more packages whose build takes a very long time to complete. (e.g. gcc, firefox, LibreOffice). This can lead to up to a day’s lag in even getting enqueued. Even if your package was part of the same batch, it will still wait for all packages in the batch to complete before the tag occurs.
As of this writing, we are currently investigating having certain extremely large packages built and tagged directly and without batching in order to shorten the average batch time.
Why do batches not run in parallel?
Simply put, until the previous batch is complete, there’s no way to know if a further batch relies on one or more changes from the previous batch. This is a problem we’re hoping might have a solution down the line, if it becomes possible to create “nested” side-tags (side-tags derived from another side-tag instead of a base tag). Today however, serialization is the only safe approach.
Why are some packages not tagged into the batch side-tag?
Some packages have known incompatibilities, such as libllvm and OCAML. The libraries produced in the ELN build and Rawhide build are API or ABI incompatible and therefore cannot be tagged in safely. We have to rely on the previous ELN version of the build in the buildroot.
Why do you not tag successes back into ELN immediately?
Despite the fact that we do not block ELN builds going to the stable repository based on test results, we do want to know about and address any issues revealed. Many packages are interdependent and it’s far simpler to test the result of all the builds collectively, once we know they have all been rebuilt.
- There are certain packages that we exclude from this so that the Rawhide package is not used in the ELN buildroot; see the
skip_tagsection of the configuration file for the current set. ↩︎ - In the case of very large batches (such as mass-rebuilds), the set of packages may be split into more than one Bodhi update, to avoid in overtaxing things. ↩︎