Optimize Memory

Report an issue View source Nightly · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

This page describes how to limit and reduce the memory Bazel uses.

Running Bazel with Limited RAM

In certain situations, you may want Bazel to use minimal memory. You can set the maximum heap via the startup flag --host_jvm_args, like --host_jvm_args=-Xmx2g.

Trade incremental build speeds for memory

If your builds are too big, Bazel may throw an OutOfMemoryError (OOM) when it doesn't have enough memory. You can make Bazel use less memory, at the cost of slower incremental builds, by passing the following command flags: --discard_analysis_cache, --nokeep_state_after_build, and --notrack_incremental_state.

These flags will minimize the memory that Bazel uses in a build, at the cost of making future builds slower than a standard incremental build would be.

You can also pass any one of these flags individually:

  • --discard_analysis_cache will reduce the memory used during execution (not analysis). Incremental builds will not have to redo package loading, but will have to redo analysis and execution (although the on-disk action cache can prevent most re-execution).
  • --notrack_incremental_state will not store any edges in Bazel's internal dependency graph, so that it is unusable for incremental builds. The next build will discard that data, but it is preserved until then, for internal debugging, unless --nokeep_state_after_build is specified.
  • --nokeep_state_after_build will discard all data after the build, so that incremental builds have to build from scratch (except for the on-disk action cache). Alone, it does not affect the high-water mark of the current build.

Trade build flexibility for memory with Skyfocus (Experimental)

If you want to make Bazel use less memory and retain incremental build speeds, you can tell Bazel the working set of files that you will be modifying, and Bazel will only keep state needed to correctly incrementally rebuild changes to those files. This feature is called Skyfocus.

To use Skyfocus, pass the --experimental_enable_skyfocus flag:

bazel build //pkg:target --experimental_enable_skyfocus

By default, the working set will be the set of files next to the target being built. In the example, all files in //pkg will be kept in the working set, and changes to files outside of the working set will be disallowed, until you issue bazel clean or restart the Bazel server.

If you want to specify an exact set of files or directories, use the --experimental_working_set flag, like so:

bazel build //pkg:target --experimental_enable_skyfocus
--experimental_working_set=path/to/another/dir,path/to/tests/dir

You can also pass --experimental_skyfocus_dump_post_gc_stats to show the memory reduction amount:

Putting it altogether, you should see something like this:

$ bazel test //pkg:target //tests/... --experimental_enable_skyfocus --experimental_working_set dir1,dir2,dir3/subdir --experimental_skyfocus_dump_post_gc_stats
INFO: --experimental_enable_skyfocus is enabled. Blaze will reclaim memory not needed to build the working set. Run 'blaze dump --skyframe=working_set' to show the working set, after this command.
WARNING: Changes outside of the working set will cause a build error.
INFO: Analyzed 149 targets (4533 packages loaded, 169438 targets configured).
INFO: Found 25 targets and 124 test targets...
INFO: Updated working set successfully.
INFO: Focusing on 334 roots, 3 leafs... (use --experimental_skyfocus_dump_keys to show them)
INFO: Heap: 1237MB -> 676MB (-45.31%)
INFO: Elapsed time: 192.670s ...
INFO: Build completed successfully, 62303 total actions

For this example, using Skyfocus allowed Bazel to drop 561MB (45%) of memory, and incremental builds to handle changes to files under dir1, dir2, and dir3/subdir will retain their fast speeds, with the tradeoff that Bazel cannot rebuild changed files outside of these directories.

Memory Profiling

Bazel comes with a built-in memory profiler that can help you check your rule’s memory use. Read more about this process on the Memory Profiling section of our documentation on how to improve the performance of custom rules.