Skip to main content

What's New in Bazel 6.0

Brentley Jones
Brentley Jones, Developer Evangelist @ BuildBuddy

Bazel 6.0 includes over 3,100 changes since 5.4. It's the latest major release, following the release of 5.0 in January of this year, and it's Bazel's third 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.

Similar to Bazel 5.0's changes, the end result was quite big, 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.


  • --experimental_build_transitive_python_runfiles is now --incompatible_build_transitive_python_runfiles. (36afffa)
  • --experimental_debug_spawn_scheduler is now --debug_spawn_scheduler. (e38c73f)
  • --experimental_desugar_java8_libs is now --desugar_java8_libs. (e38c73f)
  • --experimental_enable_bzlmod is now --enable_bzlmod. (f106d5c)
  • --experimental_local_execution_delay is now --dynamic_local_execution_delay. (e38c73f)
  • --experimental_worker_max_multiplex_instances is now --worker_max_multiplex_instances. (e38c73f)

Default values changedโ€‹

  • --analysis_testing_deps_limit=1000 (21dfe4c)
  • --experimental_allow_unresolved_symlinks=true (3d5c5d7)
  • --experimental_keep_config_nodes_on_analysis_discard=true (60523c7)
  • --experimental_collect_local_sandbox_action_metrics=true (60523c7)
  • --experimental_incremental_dexing_after_proguard=50 (ce55639)
  • --experimental_incremental_dexing_after_proguard_by_default=true (ce55639)
  • --experimental_inmemory_dotd_files=true (d44f11b)
  • --experimental_inmemory_jdeps_files=true (822e049)
  • --experimental_keep_config_nodes_on_analysis_discard=false (2f9f842)
  • --experimental_use_dex_splitter_for_incremental_dexing=true (ce55639)
  • --incompatible_always_include_files_in_data=true (0caf488)
  • --incompatible_enforce_config_setting_visibility=true (aad2db2)
  • --incompatible_existing_rules_immutable_view=true (74b7dd5)
  • --incompatible_remote_results_ignore_disk=true (4c56431)
  • --incompatible_use_platforms_repo_for_constraints=true (f137e64)
  • --use_top_level_targets_for_symlinks=true (6452024)
  • --use_workers_with_dexbuilder=true (0c3f528)


  • --allowed_local_actions_regex (16f2eec)
  • --experimental_spawn_scheduler (da6f802)


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

  • --distinct_host_configuration (78d0fc9)
  • --dynamic_worker_strategy (db64e7e)
  • --experimental_allow_top_level_aspects_parameters (bccbcbf)
  • --experimental_dynamic_skip_first_build (db64e7e)
  • --experimental_keep_config_nodes_on_analysis_discard (75bb463)
  • --experimental_multi_cpu (85bfefe)
  • --experimental_skyframe_prepare_analysis (f22e63d)
  • --incompatible_disable_managed_directories (cbf8159)
  • --incompatible_disable_third_party_license_checking (0aa750b)
  • --incompatible_disallow_legacy_py_provider (f068b31)
  • --incompatible_override_toolchain_transition (2d5375c)


  • --all_incompatible_changes (8e6c469)
  • --analysis_warnings_as_errors (8e6c469)
  • --default_android_platform (ed7a056)
  • --experimental_delay_virtual_input_materialization (c887c2a)
  • --experimental_enable_cc_toolchain_config_info (8e6c469)
  • --experimental_local_memory_estimate (361ce67)
  • --experimental_persistent_test_runner (1f33504)
  • --experimental_profile_cpu_usage (8e6c469)
  • --experimental_required_aspects (8e6c469)
  • --experimental_shadowed_action (8e6c469)
  • --experimental_skyframe_eval_with_ordered_list (8e6c469)
  • --experimental_worker_allow_json_protocol (09df7c0)
  • --extra_proguard_specs (ab51d2e)
  • --forceJumbo (9cb551c)
  • --incompatible_applicable_licenses (29e4aee)
  • --incompatible_disable_depset_items (bf30d81)
  • --incompatible_disable_late_bound_option_defaults (8e6c469)
  • --incompatible_disable_legacy_proto_provider (8e6c469)
  • --incompatible_disable_proto_source_root (8e6c469)
  • --incompatible_do_not_emit_buggy_external_repo_import (8e6c469)
  • --incompatible_enable_exports_provider (01a46f0)
  • --incompatible_linkopts_to_linklibs (34ce6a2)
  • --incompatible_proto_output_v2 (6b6c63e)
  • --incompatible_use_native_patch (8e6c469)
  • --ios_cpu (684fb0a)
  • --json_trace_compression (8e6c469)
  • --master_bazelrc (96c8a90)
  • --max-bytes-wasted-per-file (e846207)
  • --minimal-main-dex (63ddfc4)
  • --remote_allow_symlink_upload (4f557e8)
  • --set-max-idx-number (e846207)
  • --show_task_finish (2e48994)
  • --ui (8e6c469)


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 6.0.

Remote caching (RBC)โ€‹

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:

  • Added the --experimental_remote_downloader_local_fallback flag, which causes the remote downloader to fallback to normal fetching. (7b141c1)
  • Added the --incompatible_remote_downloader_send_all_headers flag, which causes all values of a multi-value header to be sent with Remote Downloader. (b750f8c)
  • The --experimental_action_cache_store_output_metadata flag is now enabled by default when using the --remote_download_* flags. (e5f92a4)
  • Outputs downloaded with --experimental_remote_download_regex no longer block spawn execution. (e01e7f5)
  • --experimental_remote_download_regex now matches on execution root relative paths. (bb8e6ec)
  • Top-level outputs are now always downloaded when using --remote_download_toplevel. (b6f3111)
  • bazel run now works with --remote_download_minimal. (845077f)
  • When using Build without the Bytes, AC results in the disk cache are now validated to be complete. (21b0992)
  • Outputs and stdErr are now always downloaded. (b303cd1)
  • Symlinked targets are no longer unnecessarily downloaded. (32b0f5a)
  • Downloads now use a priority system to improve critical path performance. (05b9739)
  • HTTP remote caches now support client TLS authentication. (aaf65b9)
  • Headers are no longer included in FetchBlobRequest. (7aa69a9)
  • AC uploads will no longer error if --remote_upload_local_results=true and GetCapabilities returns update_enabled=false. (f589512)
  • Fixed hanging when failing to upload action inputs. (8b61746)

Remote execution (RBE)โ€‹

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:

  • Added the --experimental_remote_mark_tool_inputs flag, which marks tool inputs for remote executors, which in turn allows them to implement remote persistent workers. (72b481a)
  • Added the --incompatible_remote_dangling_symlinks flag, which allows symlinks in action outputs to dangle. (5b46a48)
  • Added the --remote_print_execution_messages flag, which allows control over when to print remote execution messages. (8b57c58)
  • Added the exclusive-if-local tag, for disabling parallel local test execution but allowing remote execution if requested. (8936828)
  • Added support for remotely generating unresolved symlinks. (ca95fec)
  • Fixed formatting of non-ASCII text. (c55b01e)

Dynamic executionโ€‹

Dynamic execution allows for Bazel to race remote and local execution of actions, potentially allowing you to get the benefit of both modes, without the drawbacks of either. Bazel 6.0 included a number of changes to dynamic execution, almost all of them behind new experimental flags:

  • Added the --experimental_dynamic_exclude_tools flag, which prevents dynamic execution for tools. (9a52a27)
  • Added the --experimental_dynamic_local_load_factor flag, which controls how much load from dynamic execution to put on the local machine. (d5c4f55)
  • Added the --experimental_dynamic_slow_remote_time flag, which starts locally scheduling actions above a certain age in dynamic scheduling. (88f605c)
  • Added the --experimental_prioritize_local_actions flag, which prioritizes local-only actions over dynamically executed actions for local resources. (8fa3ccb)

Local executionโ€‹

In buck2, local execution is a specialization of remote execution. So I'm going to use that as the reason that this section is listed under the "Remote" section, and not because I don't want to reorganize this post just to fit in a couple neat local execution changes ๐Ÿ˜‰:

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.

  • Added the --bep_maximum_open_remote_upload_files flag, which allows control over the maximum number of open files allowed during BEP artifact upload. (46104c6)
  • Added the --bes_check_preceding_lifecycle_events flag, which tells BES to check whether it previously received InvocationAttemptStarted and BuildEnqueued events matching the current tool event. (14b5c41)
  • Added the --experimental_build_event_upload_max_retries and --experimental_build_event_upload_retry_minimum_delay flags, which allow for configuring the behavior of BES uploader retires. (e7218d5)
  • Added the --experimental_remote_build_event_upload flag, which controls the way Bazel uploads files referenced in BEP to remote caches. (6b52772)
  • BES RPC calls now include request metadata. (dbcf260)


Bazel offers various methods to gain insight into your build. I cover some of the notable changes to those methods below.

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:

  • Added the digest and length fields to File. (da6d949)
  • Added the BuildMetrics.network_metrics field. (9bc9096)
  • Added the MemoryMetrics.peak_post_gc_tenured_space_heap_size field. (a9ac2b6)
  • Added the WorkerMetrics.last_action_start_time_in_ms field. (d233c89)
  • Changed the semantics of build_event_stream.BuildMetrics.PackageMetrics.packages_loaded to be the number of packages successfully loaded. (d8c25fc)
  • Deprecated AnomalyReport. (286fb80)

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:

  • Added action mnemonics. (e78fd2e)
  • Added the --experimental_collect_load_average_in_profiler flag, which adds the system's overall load average. (b4dbed0)
  • Added the --experimental_collect_system_network_usage flag, which adds system network usage. (e382cb2)
  • Added the --experimental_collect_worker_data_in_profiler flag, which adds worker memory usage. (be5354b)
  • Improved reporting of critical path components. (3d2bb2a)
  • Made the sort_index value always a string. (081f831)

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 few noticeable additions:

  • Added the --experimental_execution_log_spawn_metrics flag, which causes spawn metrics in be included in the execution log. (b4b8b26)
  • Added the SpawnExec.digest field. (b2cbc9a)
  • Added the SpawnExec.target_label field. (9f908ca)


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:

  • Added the --incompatible_package_group_includes_double_slash flag, which removes the leading // from package_group.package output. (1473988)
  • Added an optional second argument to the some operator, specifying number of nodes returned. (cc71db2)
  • Labels are decanonicalized if possible. (47b1cad)


  • Added support for queries over incompatible targets. (73b22b6)
  • Added struct, json, proto, and depset to --output=starlark. (d693465)
  • Added ConfiguredRuleInput when using --transitions, which reports the configuration dependencies are configured in. (9994c32)
  • Added more information about configurations to proto output. (29d46eb)
  • Added the Configuration.is_tool attribute to proto output. (fb92e2d)
  • Complete configurations are now included in proto output. (ac48e65)
  • --output=files now also outputs source files. (ca8674c)
  • Starlark transitions now report source code location. (5de9888)
  • Updated AnalysisProtosV2. (46a36d6)


  • Added the --include_file_write_contents flag, which includes file contents for the FileWrite action. (6d73b96)
  • Added the Configuration.is_tool attribute to the proto output. (fb92e2d)
  • Fixed formatting of non-ASCII text. (c55b01e)
  • Fixed non-deterministic sorting of execution requirements. (ec1ac2f)

Dependency managementโ€‹

A new dependency system named Bzlmod was added in Bazel 5.0, and made non-experimental in Bazel 6.0. Besides all of the changes needed to support Bzlmod, these were some other notable dependency management related changes:

  • Added the --experimental_check_external_repository_files flag, which allows disabling checking for modifications to files in external repositories. (123da96)
  • Added the build_file and build_file_content attributes to git_repository. (f5a899f)
  • Added the add_prefix attribute to http_* rules. (87c8b09)
  • Added the integrity attribute to http_file and http_jar. (e51a15f)
  • Added the workspace_root attribute to repository_ctx. (8edf6ab)
  • Added the success parameter to (5af794b)
  • Added the rename_files parameter to repository_ctx.extract. (2b02416)
  • Added host arch to repository rule markers. (16c89c1)
  • --override_repository now accepts tildes. (cc55400)
  • http_* rules now honour the NETRC environment variable. (a15f342)
  • Download progress now displays human readable bytes. (801e01c)
  • Removed support for managed directories. (cbf8159)
  • When Bzlmod is enabled, canonical label literals are used. (design doc)

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 6.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:

  • The host configuration is deprecated, and a lot of changes were made to migrate away from it and to the exec configuration.
  • Added the --incompatible_disable_starlark_host_transitions flag, which prevents rules from using the host configuration. (6464f1c)
  • Added the --experimental_exec_configuration_distinguisher flag, which changes how the platform_suffix is calculated. (51c90c7)
  • Added the exec_group argument to testing.ExecutionInfo(). (423fb20)
  • Toolchain dependencies can now be optional. (Issue #14726)
  • sh path is now selected based on execution platform instead of host platform, making it possible to execute sh actions in multi-platform builds. (eeb2e04)
  • The exec transition no longer resets any TestConfiguration.TestOptions options. (2adf003)
  • platform.exec_properties now become execution requirements. (e4c1c43)

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.


  • Added the --incompatible_sandbox_hermetic_tmp flag, which causes the sandbox to have its own dedicated empty directory mounted as /tmp rather than sharing /tmp with the host filesystem. (ae6a90a)
  • Added the --sandbox-explicit-pseudoterminal flag, which allow processes in the sandbox to open pseudoterminals. (9a13051)
  • Fixed handling of large UIDs. (467f32d)


  • Remote Xcode version is now matched more granuarly. (2ff4124)
  • clean --async is now available on macOS. (b8d0e26)
  • The @bazel_tools//tools/cpp:compiler flag now has the value clang for the auto-configured Xcode toolchain rather than the generic value compiler. (f99319f)
  • Removed some aborts from wrapped_clang. (3451774)
  • Fixed lld detection on macOS. (d9f20dc)

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.


  • D8 is now the default desugarer. (ff311f6)
  • D8 is now the default dexer. (66d07f0)
  • The D8 jar from Maven is used instead of Android Studio's. (ae24714)
  • Added the android_binary.min_sdk_version attribute. (4c3219e)
  • Added the ApkInfo.signing_min_v3_rotation_api_version attribute. (f6dbd1e)
  • Added the --mobile_install_run_deployer flag to the mobile-install command, which allows skipping the deployer after building. (0216657)
  • Added the --bytecode_optimization_pass_actions flag, which allows splitting the optimization pass into N parts. (2b44482)
  • Added the --persistent_multiplex_android_tools, --persistent_multiplex_android_resource_processor, --persistent_android_dex_desugar, and --persistent_multiplex_android_dex_desugar expansion flags, which allow for easy enabling of persistent and multiplexed Android tools (dexing, desugaring, resource, and processing) (63aace2)
  • Added the --incompatible_android_platforms_transition_updates_affected flag, which causes AndroidPlatformsTransition to also update affected by Starlark transition with the changed options. (563664e)
  • Added the --experimental_persistent_multiplex_busybox_tools flag, which enables multiplex worker support in ResourceProcessorBusyBox. (4cfd32d)
  • Added worker support to AndroidCompiledResourceMergingAction. (3df19e8)
  • Added worker support to CompatDexBuilder. (7ce1c57)
  • Added worker support to the D8 desugarer. (f32b99f)
  • Added the merged manifest to the android_deploy_info output group. (c60eb5d)
  • Added application_resources's output groups to android_binary. (bb97b02)
  • Removed support for android_binary.multidex=off. (7de4fab)
  • Reduced AndroidAssetMerger intermediate outputs. (b76cc3a)
  • Resources are now sorted to produce a consistent zip (which helps cache hit rates). (2c25f73)
  • Incremental APKs are now zipaligned before they are installed. (1b2cf8d)
  • Split APKs are now zipaligned before they are installed. (6613f6f)
  • minsdk is now added to dexing and desugaring artifacts paths. (4829960)
  • Certain Android actions now have their output paths stripped of config information. (2907d15)
  • Fixed Android's armeabi-v7a constraint. (46e0be4)


  • Added the watchos_device_arm64 cpu. (ce61164)
  • Added the watchos_device_arm64e cpu. (531df65)
  • Added the apple_common.link_multi_arch_static_library function. (8778455)
  • Added -no_deduplicate when linking with Darwin dbg/fastbuild. (9608414)
  • Added support for the static_link_cpp_runtimes feature in Apple linking. (2cc3dc4)
  • cpus for tvOS and watchOS are now correctly inferred when running on an Apple Silicon host. (da8a327)
  • 32-bit watchOS architectures are no longer included in mulit-arch builds when targeting watchOS 9.0 or greater. (01d46bb)
  • Moved -framework flags to be after the -filelist flag. (7866fd9)
  • Static frameworks are now linked into fully linked static libraries. (ccb2cc0)
  • macOS dynamic libraries now have .dylib extensions instead of .so. (6e1b440)
  • Linking cc_info is now exposed from AppleExecutableBinary and AppleDynamicFramework. (9feeb1d)
  • Removed the AppleDylibBinary and AppleLoadableBundleBinary providers. (092884b)
  • Removed the should_lipo argument from apple_common.link_multi_arch_binary. (3073f1b)
  • Removed the native apple_binary rule. (0535477)
  • Removed the native apple_static_library rule. (589354c)


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++โ€‹

  • Added the --experimental_unsupported_and_brittle_include_scanning flag, which enables C/C++ include scanning. (6522472)
  • Added the --host_per_file_copt flag. (4919d4a)
  • Added the archive_param_file feature, which allows turning off param file for archives. (bff9730)
  • Added the default_link_libs feature, which can be disabled to support pure C. (5ebb0d6)
  • Added the gcc_quoting_for_param_files feature, which enables gcc quoting for linker param files. (a9e5a32)
  • Added the treat_warnings_as_errors feature, which treats warnings as errors. (f802525)
  • Added the separate_module_headers parameter to cc_common.compile. (94f83f4)
  • Added the language parameter to cc_common.configure_features. (d308c17)
  • Added the main_output parameter to (8ac29d7)
  • Added the BAZEL_CURRENT_REPOSITORY local define to cc_* rules. (eb18166)
  • Added Action.argv support to CppCompileAction. (aaba5be)
  • Added support for vendor'ed clang (17ed57a)
  • Reverted cc_library.interface_deps back to implementation_deps. (abe6667)
  • Default flags features can now be disabled. (25d17f5)
  • The per_object_debug_info feature is now enabled by default. (5f51d21)
  • The @bazel_tools//tools/cpp:compiler flag now has the value gcc if the configured compiler is detected to be gcc. (ef3f058)
  • The malloc attribute of cc_* rules now accepts any CcInfo providing target. (1746a79)
  • The C++ archive action now has the CppArchive mnemonic. (d519fec)
  • Coverage can now be collected for external targets. (32e61b3)
  • Make variable substitution now accepts data dependencies. (46a8e09)
  • no longer stamps actions for tool dependencies. (1799842)
  • Windows interface libraries can now use the .lib extension. (af4a150)
  • Fixed cc_test to apply all compilation flags. (06f9202)
  • Fixed dynamic library lookup with remotely executed tools. (e3dcfa5)


  • Upgraded JDK11. (8f3d99a)
  • Upgraded JDK17. (fbb0958)
  • Added JDK18. (a7f1c71)
  • Added the --incompatible_disallow_java_import_empty_jars flag, which disallows empty java_import.jars attributes. (1acda6b)
  • Added the --multi_release_deploy_jars flag, which causes _deploy.jar outputs of java_binary to be Multi-Release jar files. (7f75df2)
  • Added the property, which disables the bootstrap classpath cache. (fbb68e9)
  • Added the @AutoBazelRepository annotation processor. (0f95c8a)
  • Added the add_exports and add_opens attributes to java_* rules. (2217b13)
  • Added the hermetic_srcs and lib_modules attributes to java_runtime. (79badc0)
  • Added the classpath_resources argument to java_common.compile. (37d08ed)
  • Added the resource_jars argument to java_common.compile. (80ca10b)
  • Added the --add_exports and --add_opens options to singlejar. (4ff441b)
  • Added the --hermetic_java_home option to singlejar. (341d7f3)
  • Added the --jdk_lib_modules option to singlejar. (276fb09)
  • Added the --multi_release option to singlejar. (f33ce3d)
  • Added the --output_jar_creator option to singlejar. (8b5ed8a)
  • Added a tag-based suppression mechanism for java_import.deps checking. (2930dd3)
  • Coverage can now be collected for external targets. (acbb9e1)
  • The Java runtimes now have target_compatible_with set instead of exec_compatible_with. (d5559c1)
  • ijar/java_import now preserve classes with @kotlin.Metadata annotations. (a32a0fd)
  • Hermetic packaged JDK modules now record file size in deploy JAR manifest JDK-Lib-Modules-Size attribute. (756be22)
  • TurbineTransitiveJar attributes are now recognized in ijar. (b64f734)
  • The stub template now defaults to a UTF-8 locale. (17cfa01)


  • Added support for Objective-C specific features to cc_common.configure_features. (68f29c6)
  • objc_library now requires CcInfo in its deps. (540892d)
  • Removed the ObjcProvider.direct_headers attribute. (8a2b711)


  • Added the coverage_tool attribute to py_runtime. (9d01630)
  • Added the requires-darwin execution requirement to macOS py_test targets. (32364dc)
  • Added CurrentRepository() to Python runfiles library. (d60ce2c)
  • The stub now also considers RUNFILES_DIR when no runfiles directory can be found. (c3425fe)
  • Reduced the number of imports used in the stub. (c33e44c)
  • py_*.srcs_version="PY2" is now the the same as "PY2ONLY". (ecd4c90)
  • Removed UNC path prefix on Windows-10.1607 or later. (40b95c3)

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 6.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:

  • Added the --aspects_parameters flag, which allows passing parameters to command-line aspects. (3771072)
  • Added support for using attr.bool(). (30fd508)
  • Added support for using (14292d1)
  • Added support for setting exec_compatible_with and exec_group on aspects. (7e3755d)
  • Aspects now inherit fragments from required aspects and from targets they are attached to. (b3e12ba)

Persistent workersโ€‹

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

  • Added the --experimental_total_worker_memory_limit_mb flag, which sets a limit on total worker memory usage. (8e67432)
  • Added the --experimental_worker_multiplex_sandboxing flag, which controls whether to sandbox multiplex workers that support it. (fb19a28)
  • Added the --experimental_worker_strict_flagfiles flag, which checks if the worker argument list conforms to the spec. (cb2cd9f)


As mentioned at Bazelcon, progress is being made on migrating natives rules out of Bazel and into standalone Starlark rules. In the Bazel 6.0 release progress was made on the Android, C++, Java, Objective-C, Protobuf, and Python 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:

  • Added the --incompatible_disallow_symlink_file_to_dir flag, which disallows ctx.actions.symlink from symlinking a file into a directory. (54f11fe)
  • Added the --incompatible_remove_rule_name_parameter flag, which disables the parameter. (6449105)
  • Added the --experimental_debug_selects_always_succeed flag, which causes select functions with no matching clause to return an empty value, instead of failing. (b615d0d)
  • Added the --experimental_get_fixed_configured_action_env flag, which causes action.env to return fixed environment variables specified through features configuration. (e82beda)
  • Added the --experimental_lazy_template_expansion flag, which adds support for lazily computed substitutions to ctx.actions.expand_template(). (cc74b11)
  • Added dict union operators (| and |=). (b1deea4)
  • Added the coverage_support_files and coverage_environment parameters to coverage_common.instrumented_files_info. (0a13dd6)
  • Added the init parameter to provider(), which allows for performing pre-processing and validation of field values. (fc13ba2)
  • Added load visibility. (docs)
  • dict() and dict.update() now accept arbitrary maps, not just dicts. (dfa9c62)
  • testing.ExecutionInfo can now be used as a provider key. (40a6cb0)
  • The symlinks and root_symlinks parameters of the ctx.runfiles function now accept depsets. (aaf87f4)
  • Starlark flags no longer warn for incompatible commands. (f717d6a)
  • Moved analysis_test to testing.analysis_test. (5e80514)
  • The \a, \b, \f, and \v escape sequences are now supported. (d0fde13)
  • print() statements are now emitted only if the line of code is executed. (3bda5c9)
  • native.existing_rule/s() with --incompatible_existing_rules_immutable_view can now be encoded as json and passed as **kwargs. (cf99f84)
  • Fixed incremental builds that transition on flags when the default value of those flags changed. (2f7d965)
  • Fixed preserving the relative order of explicit and expanded Starlark flags. (9f2542f)
  • Fixed ctx.actions.symlink(target_path = ...) incorrectly making paths absolute. (d834905)


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:

  • Added the --experimental_output_directory_naming_scheme flag, which modifies the way the output directory is calculated. (52d1d4a)
  • Added the --incompatible_check_testonly_for_output_files flag, which checks testonly for prerequisite targets that are output files by looking up testonly of the generating rule. (65388c3)
  • Added the --incompatible_fix_package_group_reporoot_syntax flag, which changes the meaning of "//..." to refer to all packages in the current repository instead of all packages in any repository. (1473988)
  • Added the --incompatible_package_group_has_public_syntax flag, which allows writing "public" or "private" in the package_group.packages attribute to refer to all packages or no packages respectively. (1473988)
  • Added the --incompatible_unambiguous_label_stringification flag, which enables unambiguous stringification of Labels. (Issue #16196)
  • Added the bazel leaf command. (b82a8e9)
  • bazel config now shows output path prefixes. (507d85f)
  • BAZEL_TEST=1 is now set as a test environment variable. (830d464)
  • Progress updates no longer have their delay increased when there is no cursor control. (60e9bf3)
  • Fixed native rules not merging default outputs into the transitive runfiles. (7cc786a)
  • Fixed --nobuild_runfiles_links when used with --run_under (3badca3)


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

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