build-perf-diagnostics
Diagnose MSBuild build performance bottlenecks using binary log analysis. USE FOR: identifying why builds are slow by analyzing binlog performance summaries, detecting ResolveAssemblyReference (RAR) taking >5s, Roslyn analyzers consuming >30% of Csc time, single targets dominating >50% of build time…
Install / Use
npx skills add dotnet/skills --skill build-perf-diagnosticsInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
Development & EngineeringSupported Platforms
Our assessment of build-perf-diagnostics
build-perf-diagnostics scores 87/100 on our quality scale, 861st of 2,398 Development & Engineering skills we index (top 36%).
Its SKILL.md is 10 KB long, well organised into 14 sections and no code examples: a thorough specification that gives an agent plenty to work with.
With 5,471 GitHub stars, it is one of the more widely adopted skills in the catalogue.
Maintenance, license and trust
- The repository was last updated 2 days ago, so build-perf-diagnostics is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
build-perf-diagnostics compared with similar skills
All 4 of these similar skills score higher than build-perf-diagnostics; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| build-perf-diagnostics (this skill)by dotnet | 87 | 5.5k | 2d ago | SKILL.md |
| ai-job-searchby MadsLorentzen | 100 | 44.0k | 5d ago | CLAUDE.md |
| claude-howtoby luongnv89 | 100 | 41.7k | today | CLAUDE.md |
| algorithmic-artby anthropics | 100 | 177.9k | 4d ago | SKILL.md |
| pptxby anthropics | 100 | 177.9k | 4d ago | SKILL.md |
Frequently asked questions
- How do I install build-perf-diagnostics?
- Run
npx skills add dotnet/skills --skill build-perf-diagnostics. The install tabs above show the steps for each supported agent. - Which AI agents does build-perf-diagnostics work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is build-perf-diagnostics safe to use?
- It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is build-perf-diagnostics still maintained?
- The repository was last updated 2 days ago, so build-perf-diagnostics is actively maintained.
Skill content
View source on GitHubname: build-perf-diagnostics description: "Diagnose MSBuild build performance bottlenecks using binary log analysis. USE FOR: identifying why builds are slow by analyzing binlog performance summaries, detecting ResolveAssemblyReference (RAR) taking >5s, Roslyn analyzers consuming >30% of Csc time, single targets dominating >50% of build time, node utilization below 80%, excessive Copy tasks, NuGet restore running every build. Covers timeline analysis, Target/Task Performance Summary interpretation, and 7 common bottleneck categories. Use after build-perf-baseline has established measurements. DO NOT USE FOR: establishing initial baselines (use build-perf-baseline first), fixing incremental build issues (use incremental-build), parallelism tuning (use build-parallelism), non-MSBuild build systems." license: MIT
Performance Analysis Methodology
- Generate a binlog:
dotnet build /bl:{} -m - Use the binlog MCP server (
Microsoft.AITools.BinlogMcp, exposed under thebinlogMCP namespace) which is bundled with this plugin
Alternate flow when MCP is unavailable: binlog replay to text logs
- Generate a binlog:
dotnet build /bl:{} -m - Replay to diagnostic log with performance summary:
dotnet msbuild build.binlog -noconlog -fl -flp:v=diag;logfile=full.log;performancesummary - Read the performance summary (at the end of
full.log):grep "Target Performance Summary\|Task Performance Summary" -A 50 full.log - Find expensive targets and tasks: The PerformanceSummary section lists all targets/tasks sorted by cumulative time
- Check for node utilization: grep for scheduling and node messages
grep -i "node.*assigned\|building with\|scheduler" full.log | head -30 - Check analyzers: grep for analyzer timing
grep -i "analyzer.*elapsed\|Total analyzer execution time\|CompilerAnalyzerDriver" full.log
Key Metrics and Thresholds
- Build duration: what's "normal" — small project <10s, medium <60s, large <5min
- Node utilization: ideal is >80% active time across nodes. Low utilization = serialization bottleneck
- Single target domination: if one target is >50% of build time, investigate
- Analyzer time vs compile time: analyzers should be <30% of Csc task time. If higher, consider removing expensive analyzers
- RAR time: ResolveAssemblyReference >5s is concerning. >15s is pathological
Common Bottlenecks
1. ResolveAssemblyReference (RAR) Slowness
- Symptoms: RAR taking >5s per project
- Root causes: too many assembly references, network-based reference paths, large assembly search paths
- Fixes: reduce reference count, use
<DesignTimeBuild>false</DesignTimeBuild>for RAR-heavy analysis, set<ResolveAssemblyReferencesSilent>true</ResolveAssemblyReferencesSilent>for diagnostic - Advanced:
<DesignTimeBuild>and<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch> - Key insight: RAR runs unconditionally even on incremental builds because users may have installed targeting packs or GACed assemblies (see dotnet/msbuild#2015). With .NET Core micro-assemblies, the reference count is often very high.
- Reduce transitive references: Set
<DisableTransitiveProjectReferences>true</DisableTransitiveProjectReferences>to avoid pulling in the full transitive closure (note: projects may need to add direct references for any types they consume). UseReferenceOutputAssembly="false"on ProjectReferences that are only needed at build time (not API surface). Trim unused PackageReferences.
2. Roslyn Analyzers and Source Generators
- Symptoms: Csc task takes much longer than expected for file count (>2× clean compile time)
- Diagnosis: Check the Task Performance Summary in the replayed log for Csc task time; grep for analyzer timing messages; compare Csc duration with and without analyzers (
/p:RunAnalyzers=false) - Fixes:
- Conditionally disable in dev:
<RunAnalyzers Condition="'$(ContinuousIntegrationBuild)' != 'true'">false</RunAnalyzers> - Per-configuration:
<RunAnalyzers Condition="'$(Configuration)' == 'Debug'">false</RunAnalyzers> - Code-style only:
<EnforceCodeStyleInBuild Condition="'$(ContinuousIntegrationBuild)' == 'true'">true</EnforceCodeStyleInBuild> - Remove genuinely redundant analyzers from inner loop
- Severity config in .editorconfig for less critical rules
- Conditionally disable in dev:
- Key principle: Preserve analyzer enforcement in CI. Never just "remove" analyzers — configure them conditionally.
- GlobalPackageReference: Analyzers added via
GlobalPackageReferenceinDirectory.Packages.propsapply to ALL projects. Consider if test projects need the same analyzer set as production code. - EnforceCodeStyleInBuild: When set to
trueinDirectory.Build.props, forces code-style analysis on every build. Should be conditional on CI environment (ContinuousIntegrationBuild) to avoid slowing dev inner loop.
3. Serialization Bottlenecks (Single-threaded targets)
- Symptoms: Performance summary shows most build time concentrated in a single project; diagnostic log shows idle nodes while one works
- Common culprits: targets without proper dependency declaration, single project on critical path
- Fixes: split large projects, optimize the critical path project, ensure proper
BuildInParallel
4. Excessive File I/O (Copy tasks)
- Symptoms: Copy task shows high aggregate time
- Root causes: copying thousands of files, copying across network drives, Copy task unintentionally running once per item (per-file) instead of as a single batch (see dotnet/msbuild#12884)
- Fixes: use hardlinks (
<CreateHardLinksForCopyFilesToOutputDirectoryIfPossible>true</CreateHardLinksForCopyFilesToOutputDirectoryIfPossible>), reduce CopyToOutputDirectory items, use<UseCommonOutputDirectory>true</UseCommonOutputDirectory>when appropriate, set<SkipCopyUnchangedFiles>true</SkipCopyUnchangedFiles>, consider--artifacts-path(.NET 8+) for centralized output layout - Dev Drive: On Windows, switching to a Dev Drive (ReFS with copy-on-write and reduced Defender scans) can significantly reduce file I/O overhead for Copy-heavy builds. Recommend for both dev machines and self-hosted CI agents.
5. Evaluation Overhead
- Symptoms: build starts slow before any compilation
- Root causes: complex Directory.Build.props, wildcard globs scanning large directories, NuGetSdkResolver overhead (adds 180-400ms per project evaluation even when restored — see dotnet/msbuild#4025)
- Fixes: reduce Directory.Build.props complexity, use
<EnableDefaultItems>false</EnableDefaultItems>for legacy projects with explicit file lists, avoid NuGet-based SDK resolvers if possible - See:
eval-performanceskill for detailed guidance
6. NuGet Restore in Build
- Symptoms: restore runs every build even when unnecessary
- Fixes:
- Separate restore from build:
dotnet restorethendotnet build --no-restore - Enable static graph evaluation:
<RestoreUseStaticGraphEvaluation>true</RestoreUseStaticGraphEvaluation>in Directory.Build.props — can save significant time in large builds (results are workload-dependent)
- Separate restore from build:
7. Large Project Count and Graph Shape
- Symptoms: many small projects, each takes minimal time but overhead adds up; deep dependency chains serialize the build
- Consider: project consolidation, or use
/graphmode for better scheduling - Graph shape matters: a wide dependency graph (few levels, many parallel branches) builds faster than a deep one (many levels, serialized). Refactoring from deep to wide can yield significant improvements in both clean and incremental build times.
- Actions: look for unnecessary project dependencies, consider splitting a bottleneck project into two, or merging small leaf projects
Using Binlog Replay for Performance Analysis
Step-by-step workflow using text log replay:
- Replay with performance summary:
dotnet msbuild build.binlog -noconlog -fl -flp:v=diag;logfile=full.log;performancesummary - Read target/task performance summaries (at the end of
full.log):
This shows all targets and tasks sorted by cumulative time — equivalent to finding expensive targets/tasks.grep "Target Performance Summary\|Task Performance Summary" -A 50 full.log - Find per-project build times:
grep "done building project\|Project Performance Summary" full.log - Check parallelism (multi-node scheduling):
grep -i "node.*assigned\|RequiresLeadingNewline\|Building with" full.log | head -30 - Check analyzer overhead:
grep -i "Total analyzer execution time\|analyzer.*elapsed\|CompilerAnalyzerDriver" full.log - Drill into a specific slow target:
grep 'Target "CoreCompile"\|Target "ResolveAssemblyReferences"' full.log
Quick Wins Checklist
- [ ] Use
/maxcpucount(or-m) for parallel builds - [ ] Separate restore from build (
dotnet restorethendotnet build --no-restore) - [ ] Enable static graph restore (
<RestoreUseStaticGraphEvaluation>true</RestoreUseStaticGraphEvaluation>) - [ ] Enable hardlinks for Copy (
<CreateHardLinksForCopyFilesToOutputDirectoryIfPossible>true</CreateHardLinksForCopyFilesToOutputDirectoryIfPossible>) - [ ] Disable analyzers conditionally in dev inner loop:
<RunAnalyzers Condition="'$(ContinuousIntegrationBuild)' != 'true'">false</RunAnalyzers> - [ ] Enable reference assemblies (
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>) - [ ] Check for broken incremental builds (see
incremental-buildskill) - [ ] Check for bin/obj clashes (see
check-bin-obj-clashskill) - [ ] Use graph build (
/graph) for multi-project solutions - [ ] Use
--artifacts-path(.NET 8+) for centralized output layout - [ ] Enable Dev Drive (ReFS) on Windows dev machines and self-hosted CI
Impact Categorization
When reporting findings, categorize by impact to help prioritize fixes:
- 🔴 HIGH IMPACT (do first): Items consuming >10% of total build time, or a single target >50% of build time
- 🟡 MEDIUM IMPACT: Items consuming 2-10% of build time
- 🟢 QUICK WINS: Easy changes with modest impact (e.g., property flags in Directory.Build.props)
Related Skills
ai-job-search
44.0kThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.
claude-howto
41.7kA visual, example-driven guide to Claude Code — from basic concepts to advanced agents, with copy-paste templates that bring immediate value.
algorithmic-art
177.9kCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems.
pptx
177.9kUse this skill any time a .pptx or .potx file is involved in any way — as input, output, or both. This includes: creating slide decks, pitch decks, or presentations; reading, parsing, or extracting text from any .pptx or .potx file (even if the extracted content will be used elsewhere, like in an em…
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
