Skip to main content
Generic cloud VMs — like GitHub Actions’ ubuntu-latest — provision a fresh, empty filesystem for every job. Bazel’s output base is gone. Every action must either hit the remote cache or be re-executed from scratch. Even with a warm remote cache, the round-trip cost of fetching outputs adds up, and the Bazel JVM starts cold with no in-process state. Aspect’s CI runners are designed around Bazel’s specific requirements. They are persistent VMs that accept multiple jobs in sequence rather than terminating after one. The Bazel JVM stays running between jobs, so in-memory state — including the analysis cache — carries over. Each runner mounts a RAID0 array across multiple NVMe drives to maximize filesystem IOPS, which matters for Bazel’s heavily file-intensive output base operations. When a runner starts up, it can optionally be pre-warmed from an on-disk archive: repository rule fetches, extracted external dependencies, and a populated output base are all restored before the first job runs. This eliminates the cold-start penalty for new machines joining the pool. The runner pool auto-scales based on queue depth and scales to zero when there is no work, so you are not paying for idle machines between CI runs. Cached builds routinely complete in under one minute. Self-hosted Workflows CI runners are also substantially cheaper than the per-minute pricing on GitHub Actions, Buildkite, CircleCI, and GitLab provider-hosted runners — typically 40–80% lower CI compute spend, with the gap widening on larger instance types. Because the runners live in your own AWS or GCP account, any committed-use discounts, savings plans, or enterprise agreements you already have with your cloud provider apply directly.
To learn more about CI runners, see the Estimating the effort to build a Bazel CI/CD article.