On July 28, 2026, Uber and EngFlow co-hosted a Build Meetup at Uber’s Seattle office. This wouldn’t have been possible without the help of Sergey Balabanov at Uber, who not only presented one of the talks, but also energetically arranged and helped support this event from the Uber side. Thanks again, Sergey!
And, even though nobody planned a theme for this particular meetup (our meetups are holistically focused on “Build, Scale, Investigate”), one showed up anyway. Code is getting cheaper to produce. Uber put it flatly: “AI is a problem, apparently.” Every talk examined some part of the machinery that turns abundant code into software you can trust. Let’s take a look!
Today, the new https://bazel.build/ website has finally launched. This is the
first step in a larger evolution of Bazel's documentation story. Much of
the content remains the same (the eagle-eyed among you may notice a few new
pages), but this change marks a new era of Bazel documentation.
The Bazel site migration is more than just a fresh coat of paint. One of the
underlying motivations for this change is to empower the Bazel community to make
more changes to Bazel's documentation. Before the migration, Bazel's website was
built on Google documentation infrastructure. While the capabilities of that
infrastructure were largely sufficient for Bazel's needs up to now, the
contribution experience was not.
Today's https://bazel.build/ is built on Mintlify.
With this new platform, each incoming documentation pull request to Bazel is
automatically greeted with a preview. For even faster iteration, you can
build the site
locally. These
improvements eliminate guesswork, and better equip contributors to make changes
to the Bazel docs with confidence.
One of the classic strategies to speed up a system is to avoid redundant work. Scalable build systems like Bazel and Buck2 heavily employ this strategy in various ways, with remote caching and content-addressable storage being two prominent examples. While remote caching prevents repeating redundant build actions, content-addressable storage (CAS) exists for the purpose of data deduplication. However, traditionally CAS operates at the granularity of a single file. When you modify a single byte in a file and store it in a CAS, the CAS stores a second, complete file. Deduplication at the file level is quite palatable for smaller files; a single build invocation typically contains many thousands of small files. Who cares if we store a couple more?
However, as file sizes increase, the cost of storing yet another slightly modified version of a file becomes more expensive. Instead of tossing a couple extra kilobytes into storage, you might be storing a few more gigabytes. Now, consider where these large files come from. These large files are often outputs of build actions, and those build actions depend on many smaller inputs. As those many inputs churn, the outputs also churn. Suddenly the cost of touching a tiny little source file isn’t just the cost of uploading a new version of the source file to CAS–it’s now also the cost of all the large outputs that are produced by the build. This dictates the growth rate of your CAS storage costs, which scales directly with the number of incoming builds. At AI-scale, these costs have become more important than ever before.
In this interview, Eugene Yokota—a software build expert who spent years maintaining Scala's sbt tool at Lightbend before working with hyperscaled Bazel monorepos at Twitter and Netflix—details his multi-year project to build a Bazel-compatible remote caching system into the newly released sbt 2.0. He explores the mechanics and benefits of Bazel, such as its robust remote caching and test cycle speed, and highlights how these modern, scalable build tools can eliminate CI bottlenecks for growing teams while protecting toolchain security.
The EngFlow team recently wrapped up a successful BazelCon 2025, which marked a significant milestone: the 10th anniversary of Bazel! Seeing the energy and innovation at the conference was especially meaningful for us, as several of us have been involved in BazelCon since its inception, both as organizers and attendees. We're reflecting on the immense growth the community has achieved in the last decade and how it spearheads developer productivity across the world.
EngFlow was a platinum sponsor of the main conference, facilitated several workshops on Training Day, and co-hosted a fun Game Night with JetBrains and VirtusLab. We loved seeing and hearing from many of our customers in-person at BazelCon, as Happy Customers are at the heart of what we do!
This blog brings you highlights from the conference and satellite events.
It's been almost six years since the previous entry in this series was originally published, and there are many new topics to discuss!
The biggest change in the last few years was the introduction of Bazel modules (also known as Bzlmod) and the deprecation of WORKSPACE mode. I've updated all the previous articles to be compatible with Bazel modules, but today we'll explore newly introduced functionality: how to write a module extension, and why you'd want to do so.
This "Maintaining Compatibility" trilogy began by describing how to, well,
maintain compatibility with Bzlmod builds, legacy WORKSPACE builds, and a
range of dependency versions. However, this was only half the story. Automated
testing is essential for validating our compatibility assertions, not lying to
ourselves and our users, and preventing the undoing of our hard work.
The previous post described how to write and run tests
that enable switching between Bazel versions and the Bzlmod and legacy
WORKSPACE build modes. Those tests use the latest versions of our non-Bazel
dependencies to ensure forward compatibility.
This fourth and final part of our trilogy describes how to write tests to
validate backwards compatibility with combinations of older dependency
versions. We'll build on the techniques from the previous post, while learning
what makes these backwards compatibility tests substantially different from
other tests in the suite.
We've covered techniques for ensuring that your project remains compatible with
different Bazel versions, both Bzlmod and legacy WORKSPACE builds, and older
dependency versions. However, we shouldn't make any promises until we've
validated that these properties actually hold, preferably via automated testing
and continuous integration.
This third post in our four part trilogy covers writing Bazel tests that
allow for flexibly switching between various Bazel configurations. We'll
consider advice on how to run the tests locally while developing and how to run
them in continuous integration.