.bazelrc flags you should enable

This post has been converted to a guide: https://docs.aspect.build/guides/bazelrc

I suggest you add these lines to your .bazelrc file as early in your project as possible. Add one at a time and let the dust settle, as they can be breaking.

See a complete .bazelrc file here: https://github.com/aspect-build/bazel-examples/blob/main/bazelrc/.bazelrc

  • build --sandbox_default_allow_network=false: ensure that you don't accidentally make non-hermetic actions/tests which depend on remote services. Tag an individual target with tags=["requires-network"] to opt-out of the enforcement.

  • common --incompatible_allow_tags_propagation: ensure that tags applied in your BUILD file, like tags = ["no-remote"] get propagated to actions created by the rule. Without this option, you rely on rules authors to manually check the tags you passed and apply relevant ones to the actions they create. See https://github.com/bazelbuild/bazel/issues/7766

  • test --incompatible_exclusive_test_sandboxed: fix a bug where Bazel didn't enable sandboxing for tests with tags=["exclusive"]

  • build --incompatible_strict_action_env: don't let environment variables like $PATH sneak into the build, which can cause massive cache misses when they change.

  • build --modify_execution_info=PackageTar=+no-remote: Some actions are always IO-intensive but require little compute. It's wasteful to put the output in the remote cache, it just saturates the network and fills the cache storage causing earlier evictions. It's also not worth sending them for remote execution. For actions like PackageTar it's faster to just re-run the work locally every time. You'll have to look at an execution log to figure out which action mnemonics you care about.

  • build --nolegacy_external_runfiles: improve performance of sandbox by skipping the older my_repo/external/other_repo symlinks. Note, some rules may fail under this flag, please file issues with the rule author.

  • startup --host_jvm_args=-DBAZEL_TRACK_SOURCE_DIRECTORIES=1: ensure that the Bazel server notices when a directory changes, if you have a directory listed in the srcs of some target.

  • build --experimental_remote_merkle_tree_cache --experimental_remote_merkle_tree_cache_size=[XX]: Improve remote cache checking speed by memorizing merkle tree calculations, and tweak the amount of memory allocated to it

  • build --remote_local_fallback: If the grpc remote cache connection fails, it will fail the build, add this so it falls back to the local cache.

  • build --heap_dump_on_oom: helps you debug when Bazel runs out of memory

  • build --incompatible_remote_results_ignore_disk: If you have both --noremote_upload_local_results and --disk_cache, then this fixes a bug where Bazel doesn't write to the local disk cache as it treats as a remote cache.

  • build --incompatible_default_to_explicit_init_py: fix the wrong default that comes from Google's internal monorepo by using __init__.py to delimit a Python package

  • build --noexperimental_check_output_files --noexperimental_check_external_repository_files: Speed up all builds by not checking if output files have been modified. Also lets you hack around the output tree for local debugging. Note, the second one is only in Bazel 6.0 nightlies at present.

  • test --test_verbose_timeout_warnings: Bazel's default for test_timeout is medium (5 min), but most tests should instead be short (1 min).

  • build --incompatible_remote_build_event_upload_respect_no_cache: Don't upload artifacts referenced in the BEP if the action can't be cached remotely.

  • --bes_upload_mode=fully_async: Don't make the user wait for uploads, instead allow the bazel command to complete and exit.

  • build --experimental_reuse_sandbox_directories: Save time on Sandbox creation and deletion when many of the same kind of action run during the build.

As the very last line in .bazelrc:

  • try-import %workspace%/.bazelrc.user: allow developers to add repo-specific overrides in their own personal .bazelrc.user file. Make sure this is git-ignored.

Maybe

  • build --experimental_inprocess_symlink_creation: allows spaces in filenames which are inputs to actions.

  • test --build_tests_only: change the behavior of bazel test to not bother building targets which aren't dependencies of the tests. Matches some developer expectations.

  • Need to broadcast a message to all your Bazel users? You can use build --unconditional_warning="You can just get it to print stuff" --unconditional_warning="<0001f92f>, anything" to get a UI like

WARNING: You can just get it to print stuff
WARNING: 🤯, anything

Remove

These flags are not a good idea:

  • build --workspace_status_command=...: this should only be enabled for release builds where stamping is desirable, otherwise you spend time running git commands on every build. Consider build:release --workspace_status_command=... instead, so it's only active under --config=release.