/eval-performance
Guide for diagnosing and improving MSBuild project evaluation performance. USE FOR: builds slow before any compilation starts, high evaluation time in binlog analysis, expensive glob patterns walking large directories (node_modules, .git, bin/obj), deep import chains (>20
$ npx -y skills add dotnet/skills --skill eval-performance --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/eval-performance
Context preview
The summary Claude sees to decide when to auto-load this skill.
Guide for diagnosing and improving MSBuild project evaluation performance. USE FOR: builds slow before any compilation starts, high evaluation time in binlog analysis, expensive glob patterns walking large directories (node_modules, .git, bin/obj), deep import chains (>20
SKILL.md
eval-performance.SKILL.mdname: eval-performance
description: "Guide for diagnosing and improving MSBuild project evaluation performance. USE FOR: builds slow before any compilation starts, high evaluation time in binlog analysis, expensive glob patterns walking large directories (node_modules, .git, bin/obj), deep import chains (>20 levels), preprocessed output >10K lines indicating heavy evaluation, property functions with file I/O ($([System.IO.File]::ReadAllText(...))), multiple evaluations per project. Covers the 5 MSBuild evaluation phases, glob optimization via DefaultItemExcludes, import chain analysis with /pp preprocessing. DO NOT USE FOR: compilation-time slowness (use build-perf-diagnostics), incremental build issues (use incremental-build), non-MSBuild build systems."
license: MIT
Diagnosing MSBuild Evaluation Performance
Evaluation is the work MSBuild does *before* any target runs — reading project files, processing imports, expanding globs. This skill helps you **find and confirm** evaluation bottlenecks. Measure first; recommend a change only when a measurement proves it is warranted.
Confirm the problem before changing anything
Engage only when evaluation is *measurably* the bottleneck. Do NOT act when:
- **The slowness is during compilation or target execution, not evaluation.**
That is not an evaluation problem — use `build-perf-diagnostics` instead.
- **The complaint is "rebuilds too much" / incremental build.** Use
`incremental-build` instead.
- **You have no measurement.** If no binlog or timing summary shows evaluation
is slow, gather one first (see below). Do not guess from reading project files.
- **A pattern below appears but evaluation is already fast.** Broad globs, deep
imports, or `EnableDefaultItems` are only worth flagging when the numbers show they cost real time. A project that evaluates quickly needs no change.
When a pattern is present but unmeasured, **report it as an observation and let the user decide** — do not rewrite working configuration to match a "best practice" without evidence it costs measurable evaluation time. Prefer the smallest, most targeted change; never disable SDK defaults as a first move.
MSBuild Evaluation Phases
For a comprehensive overview of MSBuild's evaluation and execution model, see [Build process overview](https://learn.microsoft.com/en-us/visualstudio/msbuild/build-process-overview).
1. **Initial properties**: environment variables, global properties, reserved properties 2. **Imports and property evaluation**: process `<Import>`, evaluate `<PropertyGroup>` top-to-bottom 3. **Item definition evaluation**: `<ItemDefinitionGroup>` metadata defaults 4. **Item evaluation**: `<ItemGroup>` with `Include`, `Remove`, `Update`, glob expansion 5. **UsingTask evaluation**: register custom tasks
Key insight: evaluation happens BEFORE any targets run. Slow evaluation = slow build start even when nothing needs compiling.
Diagnosing Evaluation Performance
Primary: binlog MCP (preferred)
Use the **binlog MCP server** (`Microsoft.AITools.BinlogMcp`, exposed under the `binlog` MCP namespace) to analyze evaluation performance:
1. Use the evaluations tool to list all evaluations and their durations 2. Use evaluation_global_properties to check for multiple evaluations with differing global properties 3. Use evaluation_properties to inspect evaluated properties for a specific project+TFM 4. Use imports tool to analyze the import chain depth and structure 5. Use properties tool to check for expensive property function evaluations
Fallback: text-log replay and preprocessing (when MCP is unavailable)
Using binlog
1. Replay the binlog: `dotnet msbuild build.binlog -noconlog -fl -flp:v=diag;logfile=full.log` 2. Search for evaluation events: `grep -i 'Evaluation started\|Evaluation finished' full.log` 3. Multiple evaluations for the same project = overbuilding 4. Look for "Project evaluation started/finished" messages and their timestamps
Using /pp (preprocess)
- `dotnet msbuild -pp:full.xml MyProject.csproj`
- Shows the fully expanded project with ALL imports inlined
- Use to understand: what's imported, import depth, total content volume
- Large preprocessed output (>10K lines) = heavy evaluation
Using /clp:PerformanceSummary
- Add to build command for timing breakdown
- Shows evaluation time separately from target/task execution
Expensive Glob Patterns
Only pursue these remedies once a measurement shows item evaluation is slow and the globs are the cause; a custom glob that isn't walking large trees is fine.
- Globs like `**/*.cs` walk the entire directory tree
- Default SDK globs are optimized, but custom globs may not be
- Problem: globbing over `node_modules/`, `.git/`, `bin/`, `obj/` — millions of files
- Remedy: use `<DefaultItemExcludes>` to exclude large directories
- Remedy: be specific with glob paths: `src/**/*.cs` instead of `**/*.cs`
- Remedy: use `<EnableDefaultItems>false</EnableDefaultItems>` only as a last resort (loses SDK defaults) — prefer the two options above first
- Check: grep for Compile items in the diagnostic log → if Compile items include unexpected files, globs are too broad
Import Chain Analysis
- Deep import chains (>20 levels) slow evaluation
- Each import: file I/O + parse + evaluate
- Common causes: NuGet packages adding .props/.targets, framework SDK imports, Directory.Build chains
- Diagnosis: `/pp` output → search for `<!-- Importing` comments to see import tree
- Remedy (only if the chain is measurably costly): reduce transitive package imports where possible, consolidate imports
Multiple Evaluations
- A project evaluated multiple times = wasted work
- Common causes: referenced from multiple other projects with different global properties
- Each unique set of global properties = separate evaluation
- Diagnosis: `grep 'Evaluation started.*ProjectName' full.log` → if count > 1, check for differing global properties
- Fix: normalize global properties, use
Read more
name: eval-performance description: "Guide for diagnosing and improving MSBuild project evaluation performance. USE FOR: builds slow before any compilation starts, high evaluation time in binlog analysis, expensive glob patterns walking large directories (node_modules, .git, bin/obj), deep import chains (>20 levels), preprocessed output >10K lines indicating heavy evaluation, property functions with file I/O ($([System.IO.File]::ReadAllText(...))), multiple evaluations per project. Covers the 5 MSBuild evaluation phases, glob optimization via DefaultItemExcludes, import chain analysis with /pp preprocessing. DO NOT USE FOR: compilation-time slowness (use build-perf-diagnostics), incremental build issues (use incremental-build), non-MSBuild build systems." license: MIT
Diagnosing MSBuild Evaluation Performance
Evaluation is the work MSBuild does *before* any target runs — reading project files, processing imports, expanding globs. This skill helps you **find and confirm** evaluation bottlenecks. Measure first; recommend a change only when a measurement proves it is warranted.
Confirm the problem before changing anything
Engage only when evaluation is *measurably* the bottleneck. Do NOT act when:
- **The slowness is during compilation or target execution, not evaluation.**
That is not an evaluation problem — use `build-perf-diagnostics` instead.
- **The complaint is "rebuilds too much" / incremental build.** Use
`incremental-build` instead.
- **You have no measurement.** If no binlog or timing summary shows evaluation
is slow, gather one first (see below). Do not guess from reading project files.
- **A pattern below appears but evaluation is already fast.** Broad globs, deep
imports, or `EnableDefaultItems` are only worth flagging when the numbers show they cost real time. A project that evaluates quickly needs no change.
When a pattern is present but unmeasured, **report it as an observation and let the user decide** — do not rewrite working configuration to match a "best practice" without evidence it costs measurable evaluation time. Prefer the smallest, most targeted change; never disable SDK defaults as a first move.
MSBuild Evaluation Phases
For a comprehensive overview of MSBuild's evaluation and execution model, see [Build process overview](https://learn.microsoft.com/en-us/visualstudio/msbuild/build-process-overview).
1. **Initial properties**: environment variables, global properties, reserved properties 2. **Imports and property evaluation**: process `<Import>`, evaluate `<PropertyGroup>` top-to-bottom 3. **Item definition evaluation**: `<ItemDefinitionGroup>` metadata defaults 4. **Item evaluation**: `<ItemGroup>` with `Include`, `Remove`, `Update`, glob expansion 5. **UsingTask evaluation**: register custom tasks
Key insight: evaluation happens BEFORE any targets run. Slow evaluation = slow build start even when nothing needs compiling.
Diagnosing Evaluation Performance
Primary: binlog MCP (preferred)
Use the **binlog MCP server** (`Microsoft.AITools.BinlogMcp`, exposed under the `binlog` MCP namespace) to analyze evaluation performance:
1. Use the evaluations tool to list all evaluations and their durations 2. Use evaluation_global_properties to check for multiple evaluations with differing global properties 3. Use evaluation_properties to inspect evaluated properties for a specific project+TFM 4. Use imports tool to analyze the import chain depth and structure 5. Use properties tool to check for expensive property function evaluations
Fallback: text-log replay and preprocessing (when MCP is unavailable)
Using binlog
1. Replay the binlog: `dotnet msbuild build.binlog -noconlog -fl -flp:v=diag;logfile=full.log` 2. Search for evaluation events: `grep -i 'Evaluation started\|Evaluation finished' full.log` 3. Multiple evaluations for the same project = overbuilding 4. Look for "Project evaluation started/finished" messages and their timestamps
Using /pp (preprocess)
- `dotnet msbuild -pp:full.xml MyProject.csproj`
- Shows the fully expanded project with ALL imports inlined
- Use to understand: what's imported, import depth, total content volume
- Large preprocessed output (>10K lines) = heavy evaluation
Using /clp:PerformanceSummary
- Add to build command for timing breakdown
- Shows evaluation time separately from target/task execution
Expensive Glob Patterns
Only pursue these remedies once a measurement shows item evaluation is slow and the globs are the cause; a custom glob that isn't walking large trees is fine.
- Globs like `**/*.cs` walk the entire directory tree
- Default SDK globs are optimized, but custom globs may not be
- Problem: globbing over `node_modules/`, `.git/`, `bin/`, `obj/` — millions of files
- Remedy: use `<DefaultItemExcludes>` to exclude large directories
- Remedy: be specific with glob paths: `src/**/*.cs` instead of `**/*.cs`
- Remedy: use `<EnableDefaultItems>false</EnableDefaultItems>` only as a last resort (loses SDK defaults) — prefer the two options above first
- Check: grep for Compile items in the diagnostic log → if Compile items include unexpected files, globs are too broad
Import Chain Analysis
- Deep import chains (>20 levels) slow evaluation
- Each import: file I/O + parse + evaluate
- Common causes: NuGet packages adding .props/.targets, framework SDK imports, Directory.Build chains
- Diagnosis: `/pp` output → search for `<!-- Importing` comments to see import tree
- Remedy (only if the chain is measurably costly): reduce transitive package imports where possible, consolidate imports
Multiple Evaluations
- A project evaluated multiple times = wasted work
- Common causes: referenced from multiple other projects with different global properties
- Each unique set of global properties = separate evaluation
- Diagnosis: `grep 'Evaluation started.*ProjectName' full.log` → if count > 1, check for differing global properties
- Fix: normalize global properties, use
This repository contains the .NET team's curated set of core skills and custom agents for coding agents. For information about the Agent Skills standard, see agentskills.io. 📊 Dashboard - Accuracy and efficiency scoring trends for contained plugins (
Repo: dotnet/skills
Other skills on dotnet-skills.
- /csharp-scripts
Run file-based C# apps with the .NET CLI when the user explicitly wants C#/.NET code without creating a project. Use for C# language/API experiments, one-file C# apps, small multi-file C# apps composed with `#:include`/`#:exclude`, or C# file-based apps linked with `#:ref`. Do
Open skill - /dotnet-pinvoke
Correctly call native (C/C++) libraries from .NET using P/Invoke and LibraryImport. Covers function signatures, string marshalling, memory lifetime, SafeHandle, and cross-platform patterns. USE FOR: writing new P/Invoke or LibraryImport declarations, reviewing or debugging
Open skill - /nuget-trusted-publishing
Set up NuGet trusted publishing (OIDC) on a GitHub Actions repo — replaces long-lived API keys with short-lived tokens. USE FOR: trusted publishing, NuGet OIDC, keyless NuGet publish, migrate from NuGet API key, NuGet/login, secure NuGet publishing. DO NOT USE FOR: publishing to
Open skill - /technology-selection
Guides technology selection and implementation of AI and ML features in .NET 8+ applications using ML.NET, Microsoft.Extensions.AI (MEAI), Microsoft Agent Framework (MAF), GitHub Copilot SDK, ONNX Runtime, and OllamaSharp. Covers the full spectrum from classic ML through modern
Open skill - /configuring-opentelemetry-dotnet
Configure OpenTelemetry distributed tracing, metrics, and logging in ASP.NET Core using the .NET OpenTelemetry SDK. Use when adding observability, setting up OTLP exporters, creating custom metrics/spans, or troubleshooting distributed trace correlation.
Open skill - /convert-blazor-server-to-webapp
Guides conversion of a pre-.NET 8 Blazor Server app into a .NET 8+ Blazor Web App. USE FOR: migrating apps that use AddServerSideBlazor and MapBlazorHub to the AddRazorComponents/MapRazorComponents model, converting _Host.cshtml to an App.razor root component, replacing
Open skill

