Claude Code Plugins

Community-maintained marketplace

Feedback

build-parallelism

@dotnet/skills
3.1k
1

Guide for optimizing MSBuild build parallelism and multi-project scheduling. Only activate in MSBuild/.NET build context. USE FOR: builds not utilizing all CPU cores, speeding up multi-project solutions, evaluating graph build mode (/graph), build time not improving with -m flag, understanding project dependency topology. Note: /maxcpucount default is 1 (sequential) — always use -m for parallel builds. Covers /maxcpucount, graph build for better scheduling and isolation, BuildInParallel on MSBuild task, reducing unnecessary ProjectReferences, solution filters (.slnf) for building subsets. DO NOT USE FOR: single-project builds, incremental build issues (use incremental-build), compilation slowness within a project (use build-perf-diagnostics), non-MSBuild build systems. INVOKES: binlog MCP server tools (expensive_projects, expensive_targets, project_target_times); falls back to dotnet build -m, dotnet build /graph, binlog replay + grep.

Install Skill

Shared

Installs to .agents/skills, used by Codex, Amp, Warp, Cursor, OpenCode, and more.

CodexAmp
Warp
CursorOpenCode
Cline
Gemini CLI
GitHub Copilot
Personal

Available across projects.

$npx skills-installer add @dotnet/skills/build-parallelism --client shared
Project

Writes to .agents/skills.

$npx skills-installer add @dotnet/skills/build-parallelism -p --client shared
Note: Review the skill instructions before using it.

SKILL.md

name build-parallelism
description Guide for optimizing MSBuild build parallelism and multi-project scheduling. Only activate in MSBuild/.NET build context. USE FOR: builds not utilizing all CPU cores, speeding up multi-project solutions, evaluating graph build mode (/graph), build time not improving with -m flag, understanding project dependency topology. Note: /maxcpucount default is 1 (sequential) — always use -m for parallel builds. Covers /maxcpucount, graph build for better scheduling and isolation, BuildInParallel on MSBuild task, reducing unnecessary ProjectReferences, solution filters (.slnf) for building subsets. DO NOT USE FOR: single-project builds, incremental build issues (use incremental-build), compilation slowness within a project (use build-perf-diagnostics), non-MSBuild build systems. INVOKES: binlog MCP server tools (expensive_projects, expensive_targets, project_target_times); falls back to dotnet build -m, dotnet build /graph, binlog replay + grep.
license MIT

MSBuild Parallelism Model

  • /maxcpucount (or -m): number of worker nodes (processes)
  • Default: 1 node (sequential!). Always use -m for parallel builds
  • Recommended: -m without a number = use all logical processors
  • Each node builds one project at a time
  • Projects are scheduled based on dependency graph

Project Dependency Graph

  • MSBuild builds projects in dependency order (topological sort)
  • Critical path: longest chain of dependent projects determines minimum build time
  • Bottleneck: if project A depends on B, C, D and B takes 60s while C and D take 5s, B is the bottleneck
  • Diagnosis: replay binlog to diagnostic log with performancesummary and check Project Performance Summary — shows per-project time; grep for node.*assigned to check scheduling
  • Wide graphs (many independent projects) parallelize well; deep graphs (long chains) don't

Graph Build Mode (/graph)

  • dotnet build /graph or msbuild /graph
  • What it changes: MSBuild constructs the full project dependency graph BEFORE building
  • Benefits: better scheduling, avoids redundant evaluations, enables isolated builds
  • Limitations: all projects must use <ProjectReference> (no programmatic MSBuild task references)
  • When to use: large solutions with many projects, CI builds
  • When NOT to use: projects that dynamically discover references at build time

Optimizing Project References

  • Reduce unnecessary <ProjectReference> — each adds to the dependency chain
  • Use <ProjectReference ... SkipGetTargetFrameworkProperties="true"> to avoid extra evaluations
  • <ProjectReference ... ReferenceOutputAssembly="false"> for build-order-only dependencies
  • Consider if a ProjectReference should be a PackageReference instead (pre-built NuGet)
  • Use solution filters (.slnf) to build subsets of the solution

BuildInParallel

  • <MSBuild Projects="@(ProjectsToBuild)" BuildInParallel="true" /> in custom targets
  • Without BuildInParallel="true", MSBuild task batches projects sequentially
  • Ensure /maxcpucount > 1 for this to have effect

Multi-threaded MSBuild Tasks

  • Individual tasks can run multi-threaded within a single project build
  • Tasks implementing IMultiThreadableTask can run on multiple threads
  • Tasks must declare thread-safety via [MSBuildMultiThreadableTask]

Analyzing Parallelism with Binlog

Primary: binlog MCP (preferred)

Use the binlog MCP server (Microsoft.AITools.BinlogMcp, exposed under the binlog MCP namespace):

  1. Use expensive_projects tool → find the slowest projects and compare individual vs total build time
  2. Use expensive_targets tool → find bottleneck targets
  3. Use project_target_times tool → drill into a specific project's target-level timing
  4. Ideal: build time should be much less than sum of project times (parallelism)
  5. If build time ≈ sum of project times: too many serial dependencies, or one slow project blocking others

Fallback: text-log replay (when MCP is unavailable)

Step-by-step:

  1. Replay the binlog: dotnet msbuild build.binlog -noconlog -fl -flp:v=diag;logfile=full.log;performancesummary
  2. Check Project Performance Summary at the end of full.log
  3. Ideal: build time should be much less than sum of project times (parallelism)
  4. If build time ≈ sum of project times: too many serial dependencies, or one slow project blocking others
  5. grep 'Target Performance Summary' -A 30 full.log → find the bottleneck targets
  6. Consider splitting large projects or optimizing the critical path

CI/CD Parallelism Tips

  • Use -m in CI (many CI runners have multiple cores)
  • Consider splitting solution into build stages for extreme parallelism
  • Use build caching (NuGet lock files, deterministic builds) to avoid rebuilding unchanged projects
  • dotnet build /graph works well with structured CI pipelines