What’s new in Bazel 5.0

Also posted on BuildBuddy Blog

Bazel 5.0 includes nearly 3,000 changes since 4.2.2.[1] It’s the first major release since 4.0 was release in January of last year, and it’s Bazel’s second LTS release. Since there were so many changes, many of them quite impactful, I felt I needed to review them all and provide a nice summary for y’all. So that’s what I did 😄.

The end result was quite big though, so I’ve included a table of contents to allow easy navigation to the changes that interest you the most:

Command-Line Flag Changes

Bazel’s LTS strategy allows for breaking changes between major versions. In particular, it allows for command-line flags to be removed, renamed, made to do nothing, or have their default values changed. In the following sections I collected all such flag changes I could find.


Default Values Changed



These flags now do nothing, but still exist to allow for migration off of them:



One of Bazel’s most powerful features is its ability to use remote caching and remote execution. Numerous improvements and fixes to Bazel’s remote capabilities are included in Bazel 5.0.


Bazel uses gRPC as a protocol for most of its remote capabilities. There were a couple changes that applied at this foundational level:

Remote caching

Using a remote cache is one of the most popular ways of speeding up a Bazel build. Thankfully these changes make using a remote cache both more performant and more reliable:

Remote execution

For some projects, using remote execution is the ultimate performance unlock for their Bazel builds. In addition to the remote caching changes covered above, which also apply to remote execution, the following changes improve the remote execution experience:

Build Event Service (BES)

Using a build event service can give you unparalleled insight into your Bazel builds at scale. There were some nice changes to BES support, though I think the improvements to how it interacts with the remote cache are especially noteworthy.


Bazel offers various ways to gain insight into your build. It’s not too surprising then that there were over 30 changes to these capabilities in Bazel 5.0.

Build Event Protocol (BEP)

The build event protocol is used by build event services, so all of these changes could have also been listed in that section as well. The BEP can also be collected locally with --build_event_json_file and --build_event_binary_file.

The vast majority of changes added additional information to the BEP, though some are fixes and improvements:

Timing profile

The action timing profile, which is enabled by default with --profile, is viewable both locally in Chrome and on build event services. These changes add more detail and clarity to the profile:

Execution log

Bazel logs all of the spawns it executes in the execution log, which is enabled with the --execution_log_json_file or --execution_log_binary_file flags. This feature is relatively stable, with just a single noticeable change:


bazel build wasn’t the only command to get improvements in this release. Here are some changes that were made to the query family of commands:

Dependency management

A new (currently experimental) external dependency system, codenamed Bzlmod, was added in Bazel 5.0. Besides for all of the changes needed to support Bzlmod, there was one more notable dependency management related change:

Platforms and toolchains

The C++, Android, and Apple rules are being migrated to support building with Platforms. While progress has been made, they don’t fully support it yet in Bazel 5.0. For C++ projects, it’s recommended that the --incompatible_enable_cc_toolchain_resolution flag is used, to help the Bazel team discover any issues in the wide variety of projects that exist.

Here are some of the platforms and toolchains related changes which weren’t tied to any of those migrations:

Execution platforms

Execution platforms are platforms which build tools execute on. These include the host platform on which Bazel runs.

In the following sections I collected notable changes for Linux and macOS. I’m sure there were some for Windows as well, but since I don’t use Bazel on Windows, none of the changes stood out to me as pertaining only to it.


I only noticed a single change that was directly related to Linux execution:


On the other hand, macOS had a lot of changes related to it:

Target platforms

Target platforms are platforms which you are ultimately building for. I cover the Android and Apple platforms in the following sections, as they still have some functionality provided by Bazel core, instead of being fully supported by standalone Starlark rules.




While there are lots of programming languages that are supported through standalone Starlark rules, some are still written as “native” rules in Bazel core, or are bundled Starlark rules while Starlarkification is in progress. In the following sections I summarize the notable changes in support of these languages.

C and C++



Rules authoring

Bazel’s extensibility is powered by the ability to write custom rules. Most rules used in a project will be provided by open source rule sets, but projects may also define rules themselves. Bazel 5.0 includes numerous changes that make custom rules more performant, easier to write, or even expand what is possible to do with them.


Aspects allow augmenting build dependency graphs with additional information and actions. These changes expanded their capabilities:

Persistent workers

Persistent workers improve build performance by sending multiple requests to long-running processes. Here are some notable changes to persistent worker support:


As mentioned at Bazelcon, progress is being made on migrating natives rules out of Bazel and into standalone Starlark rules. In the Bazel 5.0 release progress was made on the Android, C++, Java, and Objective-C rules.

In addition to changes directly needed for Starlarkification, for which there were many and I’m not going to list them here, the Starlark language itself received performance and feature improvements:


There were a handful of changes that I couldn’t find a nice home for in the sections above, but I still felt were important or interesting enough to call attention to:


As you can see, Bazel 5.0 was a massive release. Thankfully, through the rolling releases process, people were able to test, or even actively depend on, these changes well before the first 5.0 release candidate was cut.

I expect Bazel 5.1 to be a fast follow with some changes that missed the final release candidate. Work on Bazel 6.0 is well underway as well, and I look forward to summarizing its changes later this year.

  1. The GitHub UI shows some commits that already exist in the 4.x series of releases due to cherry-picking, so the number of unique commits is actually smaller. ↩︎