Skip to content

Remote Execution

This guide explains how Bazel can execute build actions on remote machines. Remote execution helps scale your builds across multiple machines and ensures consistent build environments.

Core Concepts

What is Remote Execution?

Instead of running build actions locally, Bazel can:

  • Execute actions on remote machines
  • Cache results for reuse
  • Distribute work across many machines
  • Ensure consistent execution environments

Components

  1. Remote Executor

    • Runs build actions
    • Manages execution environment
    • Reports results back to Bazel
  2. Remote Cache

    • Stores build outputs
    • Shares results between builds
    • Reduces duplicate work
  3. Content-Addressable Storage (CAS)

    • Stores input files
    • Stores output files
    • Ensures content integrity

How Remote Execution Works

1. Action Execution Flow

2. Configuration

python
# .bazelrc
# Basic remote execution setup
build --remote_executor=grpc://remote.build.example.com
build --remote_cache=grpc://cache.build.example.com

# Optional: Remote instance name
build --remote_instance_name=projects/my-project/instances/default

# Optional: Remote header for authentication
build --remote_header=Authorization=Bearer $(cat ~/.remote_build_token)

3. Platform Requirements

python
# Define execution platform requirements
platform(
    name = "remote_platform",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:x86_64",
        "//constraints:docker",  # Custom constraint
    ],
)

# Use platform for specific targets
cc_binary(
    name = "app",
    srcs = ["app.cc"],
    target_compatible_with = [
        "@platforms//os:linux",
    ],
)

Remote Execution Features

1. Dynamic Scheduling

Bazel automatically:

  • Determines which actions can run remotely
  • Balances load across available workers
  • Handles failures and retries
python
# Some actions run locally, others remotely
build --spawn_strategy=remote,local
build --remote_local_fallback  # Use local execution if remote fails

2. Caching Behavior

Control what gets cached:

python
# Cache all successful actions
build --remote_accept_cached=true

# Cache even failed actions (useful for debugging)
build --remote_accept_cached=true
build --remote_cache_failed_actions

# Don't cache certain actions
genrule(
    name = "generate",
    srcs = ["input.txt"],
    outs = ["output.txt"],
    cmd = "date > $(OUTS)",
    tags = ["no-cache"],  # Don't cache this action
)

3. Toolchain Integration

Remote execution works with Bazel's toolchain system:

python
# Toolchain for remote execution
toolchain(
    name = "remote_cpp_toolchain",
    exec_compatible_with = [
        "@platforms//os:linux",
        "@platforms//cpu:x86_64",
    ],
    target_compatible_with = [
        "@platforms//os:linux",
        "@platforms//cpu:x86_64",
    ],
    toolchain = ":cc_toolchain",
    toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)

Best Practices

1. Action Design

Design actions to work well with remote execution:

python
# Good: Hermetic action
genrule(
    name = "good_generate",
    srcs = ["input.txt"],
    outs = ["output.txt"],
    cmd = "$(location //tools:processor) $(SRCS) > $(OUTS)",
    tools = ["//tools:processor"],  # Explicit tool dependency
)

# Bad: Non-hermetic action
genrule(
    name = "bad_generate",
    outs = ["output.txt"],
    cmd = "curl https://example.com > $(OUTS)",  # Network dependency!
)

2. Resource Management

Specify resource requirements:

python
# Indicate resource needs
genrule(
    name = "resource_heavy",
    srcs = ["large_input.txt"],
    outs = ["output.txt"],
    cmd = "$(location //tools:processor) $(SRCS) > $(OUTS)",
    tools = ["//tools:processor"],
    tags = [
        "cpu:8",        # Needs 8 CPU cores
        "memory:high",  # Needs lots of memory
    ],
)

3. Error Handling

Handle remote execution failures gracefully:

python
# .bazelrc
# Retry failed actions
build --remote_retries=3

# Fall back to local execution
build --remote_local_fallback

# Keep going even if some targets fail
build --keep_going

Common Issues and Solutions

1. Network Problems

bash
# Problem: Slow uploads
ERROR: Failed to upload to remote cache: Deadline exceeded

# Solution: Adjust timeouts
build --remote_timeout=3600  # Longer timeout

2. Cache Misses

bash
# Problem: Unexpected cache misses
INFO: Not found in remote cache

# Solution: Check action hermiticity
build --explain=explain.log  # See why cache misses occur
build --verbose_explanations

3. Platform Mismatches

bash
# Problem: Action fails on remote executor
ERROR: Action failed to execute: Platform requirements not met

# Solution: Ensure platform compatibility
build --remote_executor_platform=//platforms:remote_platform

Remote Execution Services

Bazel supports various remote execution services:

  1. Buildbarn

    • Open-source remote execution service
    • Scalable and maintainable
    • Supports dynamic workers
  2. BuildGrid

    • Another open-source implementation
    • Focus on security
    • Good integration with CI systems
  3. Google Cloud Build

    • Managed service
    • Integrated with Google Cloud
    • Automatic scaling

Next Steps

Or return to the Concepts Overview to explore other topics.

Released under the MIT License.