Back to DevOps & CI/CD

bazel-build-optimization

bazelbuild-systemmonorepoperformance-optimizationdevopsci/cdremote-executionbuild-tooling
⭐ 36.8kπŸ“„ MITπŸ•’ 2026-06-16Source β†—

Install this skill

npx skills add wshobson/agents

Works across Claude Code, Cursor, Codex, Copilot & Antigravity

Bazel build optimization focuses on accelerating development cycles and deployment speeds in complex, multi-language monorepos. By defining build targets through granular BUILD files and configuring centralized caching, this approach minimizes redundant compilations. It shifts the burden from local hardware to remote execution clusters and storage, ensuring that only modified components trigger re-builds. The process requires careful orchestration of .bazelrc flags and dependency tracking across various runtimes like TypeScript and Python. Mastering this skill involves balancing local resource utilization with high-concurrency CI/CD requirements, resulting in predictable build artifacts and shorter feedback loops for engineering teams operating at scale. This methodology replaces traditional slow build pipelines with an incremental, dependency-aware graph that scales across large codebases without duplicating compute overhead.

When to Use This Skill

  • β€’Reducing build times in monorepos exceeding thousands of packages
  • β€’Standardizing build and test environments for distributed global teams
  • β€’Enforcing strict separation between source code and generated build artifacts
  • β€’Integrating multiple language ecosystems like Python and TypeScript under one build system

How to Invoke This Skill

Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:

  • β€œOptimize my Bazel build times
  • β€œSetup remote caching for Bazel in a monorepo
  • β€œConfigure .bazelrc for CI performance
  • β€œFix slow Bazel builds and high cache misses
  • β€œDefine custom Bazel rules for my project

Pro Tips

  • πŸ’‘**Leverage Bazel's Build Event Protocol (BEP)**: Actively use BEP to generate detailed reports and visualize your build graph. This data is crucial for identifying bottlenecks, unused dependencies, and inefficient rule configurations, guiding your optimization efforts strategically.
  • πŸ’‘**Prioritize Hermeticity for Reproducibility**: Ensure all your Bazel rules and targets are fully hermetic by explicitly declaring all inputs and outputs. This guarantees reproducible builds across different environments and maximizes the effectiveness of remote caching and execution.
  • πŸ’‘**Fine-Grained Dependencies for Incremental Builds**: Structure your BUILD files with the most granular dependencies possible. This allows Bazel's dependency graph to be highly optimized, leading to significantly faster incremental builds locally and reducing cache invalidations across the team.

What this skill does

  • β€’Configuring remote caching via gRPC to share artifacts across developer machines and CI
  • β€’Implementing strict toolchain resolution to ensure reproducible build environments
  • β€’Parallelizing build tasks across high-core count remote execution nodes
  • β€’Optimizing incremental compilation through precise dependency graphing
  • β€’Managing heterogeneous language dependencies within a single workspace

When not to use it

  • βœ•Small projects or micro-repos where the maintenance overhead exceeds the build time savings
  • βœ•Teams lacking the DevOps capacity to manage persistent remote cache/execution infrastructure

Example workflow

  1. Analyze the current build graph to identify common bottlenecks and slow targets
  2. Configure .bazelrc with appropriate resource limits and remote cache endpoints
  3. Refactor BUILD files to ensure granular target visibility and dependency tracking
  4. Set up toolchain resolution for required languages like Python or Node.js
  5. Validate build performance via the Build Event Service (BES) monitoring
  6. Enable CI integration to leverage remote execution for test suites

Prerequisites

  • –Bazel installed locally
  • –Workspace-level build configuration files (.bazelrc, WORKSPACE.bazel)
  • –Existing monorepo structure

Pitfalls & limitations

  • !Over-bloating the workspace with unnecessary dependencies causing cache thrashing
  • !Incorrectly defined BUILD file visibility causing circular dependency errors
  • !Non-deterministic build results if toolchain versions are not explicitly pinned

FAQ

Why is my remote cache not improving build times?
Check your build flags to ensure local results are being uploaded and that your CI/CD environment has read/write access to the cache bucket.
Does Bazel support mixed-language projects?
Yes, Bazel handles multi-language monorepos effectively by defining specific rules for each toolchain while maintaining a unified dependency graph.
What is the difference between a Target and a Package?
A package is a directory containing a BUILD file, while a target represents a specific buildable unit within that file.

How it compares

Unlike manual scripts or generic CI steps that often rebuild the entire repository, this skill enforces a strict, cached graph that only processes modified sub-trees.

Source & trust

⭐ 37k starsπŸ“„ MITπŸ•’ Updated 2026-06-16
πŸ“„ Full skill instructions β€” original source: wshobson/agents
# Bazel Build Optimization

Production patterns for Bazel in large-scale monorepos.

## When to Use This Skill

- Setting up Bazel for monorepos
- Configuring remote caching/execution
- Optimizing build times
- Writing custom Bazel rules
- Debugging build issues
- Migrating to Bazel

## Core Concepts

### 1. Bazel Architecture

workspace/
β”œβ”€β”€ WORKSPACE.bazel # External dependencies
β”œβ”€β”€ .bazelrc # Build configurations
β”œβ”€β”€ .bazelversion # Bazel version
β”œβ”€β”€ BUILD.bazel # Root build file
β”œβ”€β”€ apps/
β”‚ └── web/
β”‚ └── BUILD.bazel
β”œβ”€β”€ libs/
β”‚ └── utils/
β”‚ └── BUILD.bazel
└── tools/
└── bazel/
└── rules/


### 2. Key Concepts

| Concept | Description |
| ----------- | -------------------------------------- |
| **Target** | Buildable unit (library, binary, test) |
| **Package** | Directory with BUILD file |
| **Label** | Target identifier //path/to:target |
| **Rule** | Defines how to build a target |
| **Aspect** | Cross-cutting build behavior |

## Templates

### Template 1: WORKSPACE Configuration

# WORKSPACE.bazel
workspace(name = "myproject")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

# Rules for JavaScript/TypeScript
http_archive(
name = "aspect_rules_js",
sha256 = "...",
strip_prefix = "rules_js-1.34.0",
url = "https://github.com/aspect-build/rules_js/releases/download/v1.34.0/rules_js-v1.34.0.tar.gz",
)

load("@aspect_rules_js//js:repositories.bzl", "rules_js_dependencies")
rules_js_dependencies()

load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains")
nodejs_register_toolchains(
name = "nodejs",
node_version = "20.9.0",
)

load("@aspect_rules_js//npm:repositories.bzl", "npm_translate_lock")
npm_translate_lock(
name = "npm",
pnpm_lock = "//:pnpm-lock.yaml",
verify_node_modules_ignored = "//:.bazelignore",
)

load("@npm//:repositories.bzl", "npm_repositories")
npm_repositories()

# Rules for Python
http_archive(
name = "rules_python",
sha256 = "...",
strip_prefix = "rules_python-0.27.0",
url = "https://github.com/bazelbuild/rules_python/releases/download/0.27.0/rules_python-0.27.0.tar.gz",
)

load("@rules_python//python:repositories.bzl", "py_repositories")
py_repositories()


### Template 2: .bazelrc Configuration

# .bazelrc

# Build settings
build --enable_platform_specific_config
build --incompatible_enable_cc_toolchain_resolution
build --experimental_strict_conflict_checks

# Performance
build --jobs=auto
build --local_cpu_resources=HOST_CPUS*.75
build --local_ram_resources=HOST_RAM*.75

# Caching
build --disk_cache=~/.cache/bazel-disk
build --repository_cache=~/.cache/bazel-repo

# Remote caching (optional)
build:remote-cache --remote_cache=grpcs://cache.example.com
build:remote-cache --remote_upload_local_results=true
build:remote-cache --remote_timeout=3600

# Remote execution (optional)
build:remote-exec --remote_executor=grpcs://remote.example.com
build:remote-exec --remote_instance_name=projects/myproject/instances/default
build:remote-exec --jobs=500

# Platform configurations
build:linux --platforms=//platforms:linux_x86_64
build:macos --platforms=//platforms:macos_arm64

# CI configuration
build:ci --config=remote-cache
build:ci --build_metadata=ROLE=CI
build:ci --bes_results_url=https://results.example.com/invocation/
build:ci --bes_backend=grpcs://bes.example.com

# Test settings
test --test_output=errors
test --test_summary=detailed

# Coverage
coverage --combined_report=lcov
coverage --instrumentation_filter="//..."

# Convenience aliases
build:opt --compilation_mode=opt
build:dbg --compilation_mode=dbg

# Import user settings
try-import %workspace%/user.bazelrc


### Template 3: TypeScript Library BUILD

# libs/utils/BUILD.bazel
load("@aspect_rules_ts//ts:defs.bzl", "ts_project")
load("@aspect_rules_js//js:defs.bzl", "js_library")
load("@npm//:defs.bzl", "npm_link_all_packages")

npm_link_all_packages(name = "node_modules")

ts_project(
name = "utils_ts",
srcs = glob(["src/**/*.ts"]),
declaration = True,
source_map = True,
tsconfig = "//:tsconfig.json",
deps = [
":node_modules/@types/node",
],
)

js_library(
name = "utils",
srcs = [":utils_ts"],
visibility = ["//visibility:public"],
)

# Tests
load("@aspect_rules_jest//jest:defs.bzl", "jest_test")

jest_test(
name = "utils_test",
config = "//:jest.config.js",
data = [
":utils",
"//:node_modules/jest",
],
node_modules = "//:node_modules",
)


### Template 4: Python Library BUILD

# libs/ml/BUILD.bazel
load("@rules_python//python:defs.bzl", "py_library", "py_test", "py_binary")
load("@pip//:requirements.bzl", "requirement")

py_library(
name = "ml",
srcs = glob(["src/**/*.py"]),
deps = [
requirement("numpy"),
requirement("pandas"),
requirement("scikit-learn"),
"//libs/utils:utils_py",
],
visibility = ["//visibility:public"],
)

py_test(
name = "ml_test",
srcs = glob(["tests/**/*.py"]),
deps = [
":ml",
requirement("pytest"),
],
size = "medium",
timeout = "moderate",
)

py_binary(
name = "train",
srcs = ["train.py"],
deps = [":ml"],
data = ["//data:training_data"],
)


### Template 5: Custom Rule for Docker

# tools/bazel/rules/docker.bzl
def _docker_image_impl(ctx):
dockerfile = ctx.file.dockerfile
base_image = ctx.attr.base_image
layers = ctx.files.layers

# Build the image
output = ctx.actions.declare_file(ctx.attr.name + ".tar")

args = ctx.actions.args()
args.add("--dockerfile", dockerfile)
args.add("--output", output)
args.add("--base", base_image)
args.add_all("--layer", layers)

ctx.actions.run(
inputs = [dockerfile] + layers,
outputs = [output],
executable = ctx.executable._builder,
arguments = [args],
mnemonic = "DockerBuild",
progress_message = "Building Docker image %s" % ctx.label,
)

return [DefaultInfo(files = depset([output]))]

docker_image = rule(
implementation = _docker_image_impl,
attrs = {
"dockerfile": attr.label(
allow_single_file = [".dockerfile", "Dockerfile"],
mandatory = True,
),
"base_image": attr.string(mandatory = True),
"layers": attr.label_list(allow_files = True),
"_builder": attr.label(
default = "//tools/docker:builder",
executable = True,
cfg = "exec",
),
},
)


### Template 6: Query and Dependency Analysis

# Find all dependencies of a target
bazel query "deps(//apps/web:web)"

# Find reverse dependencies (what depends on this)
bazel query "rdeps(//..., //libs/utils:utils)"

# Find all targets in a package
bazel query "//libs/..."

# Find changed targets since commit
bazel query "rdeps(//..., set($(git diff --name-only HEAD~1 | sed 's/.*/"&"/' | tr '\n' ' ')))"

# Generate dependency graph
bazel query "deps(//apps/web:web)" --output=graph | dot -Tpng > deps.png

# Find all test targets
bazel query "kind('.*_test', //...)"

# Find targets with specific tag
bazel query "attr(tags, 'integration', //...)"

# Compute build graph size
bazel query "deps(//...)" --output=package | wc -l


### Template 7: Remote Execution Setup

# platforms/BUILD.bazel
platform(
name = "linux_x86_64",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
],
exec_properties = {
"container-image": "docker://gcr.io/myproject/bazel-worker:latest",
"OSFamily": "Linux",
},
)

platform(
name = "remote_linux",
parents = [":linux_x86_64"],
exec_properties = {
"Pool": "default",
"dockerNetwork": "standard",
},
)

# toolchains/BUILD.bazel
toolchain(
name = "cc_toolchain_linux",
exec_compatible_with = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
],
target_compatible_with = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
],
toolchain = "@remotejdk11_linux//:jdk",
toolchain_type = "@bazel_tools//tools/jdk:runtime_toolchain_type",
)


## Performance Optimization

# Profile build
bazel build //... --profile=profile.json
bazel analyze-profile profile.json

# Identify slow actions
bazel build //... --execution_log_json_file=exec_log.json

# Memory profiling
bazel build //... --memory_profile=memory.json

# Skip analysis cache
bazel build //... --notrack_incremental_state


## Best Practices

### Do's

- **Use fine-grained targets** - Better caching
- **Pin dependencies** - Reproducible builds
- **Enable remote caching** - Share build artifacts
- **Use visibility wisely** - Enforce architecture
- **Write BUILD files per directory** - Standard convention

### Don'ts

- **Don't use glob for deps** - Explicit is better
- **Don't commit bazel-\* dirs** - Add to .gitignore
- **Don't skip WORKSPACE setup** - Foundation of build
- **Don't ignore build warnings** - Technical debt

## Resources

- [Bazel Documentation](https://bazel.build/docs)
- [Bazel Remote Execution](https://bazel.build/docs/remote-execution)
- [rules_js](https://github.com/aspect-build/rules_js)

How to Use This Skill Unit

Option A: Project-Specific (Recommended)

  1. Click "Download" above
  2. In your project, create the directory: .agent/skills/bazel-build-optimization/
  3. Save the file as SKILL.md
  4. The agent will automatically discover the skill based on its description.

Option B: Global Installation (All Agents)

Save the file to these locations to make it available across all projects:

  • Claude Code: ~/.claude/skills/wshobson/agents/bazel-build-optimization/SKILL.md
  • Cursor: ~/.cursor/skills/wshobson/agents/bazel-build-optimization/SKILL.md
  • Antigravity: ~/.gemini/antigravity/skills/wshobson/agents/bazel-build-optimization/SKILL.md

πŸš€ Install with CLI:
npx skills add wshobson/agents

Read the Master Guide: Mastering Agent Skills β†’

Related Skill Units

Recommended Rules

View more rules β†’

Recommended Workflows

View more workflows β†’

Recommended MCP Servers

View more MCP servers β†’

Take It Further

Maximize your productivity with these powerful resources

πŸ“‹

Define Your Standards

Set up coding standards to ensure this workflow produces consistent, high-quality results.

Browse Rules Library
πŸ“–

Master Workflows

Learn how to create custom workflows, use Turbo Mode, and build your automation library.

Complete Guide

How to use this Skill in Claude Code & Cursor

For Claude Code (CLI)

To use this skill in Claude Code, copy the rule content into your project's custom instructions or follow our Add-Skill CLI guide. This ensures Claude follows your standards during every code generation.

For Cursor & Windsurf

For Cursor or Windsurf, individual skills are best used in the "Rules for AI" section. This specific unit helps the agent avoid devops & ci/cd issues, leading to cleaner, more efficient code.

Why the skill format matters: the standardized Agent Skills format lets your AI agent load detailed instructions only when they are relevant, keeping your prompt clean while improving results.

Source & attribution

This skill is categorized under DevOps & CI/CD and is published by W. Shobson, maintained in wshobson/agents.

← Browse All Agent Skills
Sponsored AI assistant. Recommendations may be paid.