Skip to main content
Try these when CI builds are slower or more expensive than they should be. They’re independent: start with whichever matches what you see. On Aspect Workflows CI runners, also see Optimizing CI runners.

Enable Build without the Bytes (BWOB)

Bazel 7 defaults to --remote_download_toplevel. On CI, --remote_download_minimal downloads less; set it under build:ci on any version. Build without the Bytes has the flag and where to put it. Then turn --config=ci on for CI: pass --config=ci in the job’s bazel calls, or add it automatically for Aspect CLI tasks in .aspect/config.axl:
.aspect/config.axl

Diagnose non-determinism and improve cache hit rate

A cache hit rate below 95% usually signals non-determinism: an action produces different outputs from the same inputs, so the actions that depend on it miss the cache.
  1. Check the cache hit rate on the build’s Cache tab in the Build Results UI. Target above 95%. The same tab lists the misses and their reasons. On a self-hosted deployment, the Grafana dashboards also chart the hit rate across builds.
  2. Run aspect cache diff on a commit CI has already built. It lists the actions that missed the cache and the tests they affect, without running any tests.
  3. To find what makes a missed action non-deterministic, collect two execution logs on the same commit:
    • Pass --execution_log_compact_file=/tmp/exec.log to your aspect build or aspect test invocation.
    • For the second run, make sure a different machine handles the job, so nothing comes from the first run’s local state. Provider-hosted runners give every job a fresh machine. On persistent runners, including Aspect Workflows CI runners, add a workflow that runs the same job twice in parallel, so the two runs are guaranteed to land on different machines.
    • Download the resulting log artifacts from each CI run.
  4. Compare the two logs using Bazel’s guide to debugging remote cache hits to identify the non-deterministic actions.
Execution log files are often large. Use a commit with no source changes for the second run to eliminate legitimate cache misses as a variable.