You've been there. A service that was fine six months ago now crawls under load, and nobody can pinpoint why. You open the profiler, stare at a flame graph dense enough to wallpaper a room, and wonder if there's a faster way to figure out which of your 400 allocations per request actually matters. Traditional profiling has always demanded a specific kind of expertise — the kind that takes years to develop and is rarely distributed evenly across a team.

Visual Studio 2026 introduced the Copilot Profiler Agent to change that equation. Rather than replacing the profiler, it sits on top of Visual Studio's existing performance tools and uses GitHub Copilot to interpret the data, generate benchmarks, and suggest fixes — then validates those fixes with real measurements. It's not a magic button, but it genuinely lowers the barrier to doing performance work properly.

What the Profiler Agent actually does

The Profiler Agent is an AI-powered assistant that works through Copilot Chat. You invoke it with @Profiler followed by a natural language question, and it orchestrates a multi-step workflow using the profiling tools you'd normally drive manually.

It can:

The key difference from simply asking Copilot Chat about performance is that the Profiler Agent has access to real profiling data. It doesn't guess — it measures, analyses, and measures again.

Getting started

You need Visual Studio 2026 (version 17.14 or later) and a GitHub account with Copilot access. The free tier of GitHub Copilot works.

Open the Copilot Chat window and type:

@Profiler Please evaluate the performance of this code

The agent takes it from there. It will ask permission to run the profiler, collect a trace, analyse the results, and report back with findings. You can also be more specific:

@Profiler Help me write a benchmark for the ProcessOrders method
@Profiler Why is this method taking so long to execute?

Alternatively, enable the Profiler Agent through Select Tools in the Copilot Chat panel and switch to agent mode — this lets you skip the @Profiler prefix.

The workflow in practice

The agent follows a structured loop that mirrors what an experienced performance engineer would do, but automates the tedious parts.

1. Query — You describe the problem or point the agent at a method.

2. Instrumentation — The agent adds BenchmarkDotNet to your project, installs the Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers NuGet package, and generates benchmark methods modelled after existing patterns in your codebase.

3. Measurement — It runs the benchmarks and collects profiling data into .diagsession files.

4. Analysis — The agent examines traces, identifies hot paths, and explains what it found in plain language.

5. Optimisation — It suggests code changes with reasoning, not just a diff.

6. Validation — It re-runs benchmarks to confirm the improvement, giving you before-and-after numbers.

This loop is the critical part. Performance work without measurement is guesswork, and the agent enforces measurement at every step.

A real example: optimising delegate chains

One of the most compelling demonstrations of the Profiler Agent came from the .NET team's work on CsvHelper, a widely-used library for CSV parsing.

The agent identified that writing 10,000 CSV records with 4 fields was triggering 40,000 individual delegate invocations. Each field's write operation was compiled into a separate delegate, and these were combined into a multicast delegate chain — meaning every record write involved invoking four separate compiled delegates.

The original pattern looked like this:

RecordManager.cs
var delegates = new List<Action>();

foreach (var memberMap in classMap.MemberMaps)
{
    var writeExpression = BuildWriteExpression(memberMap);
    delegates.Add(Expression.Lambda<Action>(writeExpression).Compile());
}

// Combines into a multicast delegate — each Invoke() calls all four
var combinedAction = CombineDelegates(delegates);

The agent suggested replacing the multicast delegate chain with Expression.Block, which compiles all field writes into a single delegate:

RecordManager.cs
var expressions = new List<Expression>(classMap.MemberMaps.Count);

foreach (var memberMap in classMap.MemberMaps)
{
    expressions.Add(BuildWriteExpression(memberMap));
}

var block = Expression.Block(expressions);
return Expression.Lambda<Action<TRecord>>(block, recordParameter).Compile();

The result: 40,000 delegate invocations dropped to 10,000 (one per record instead of one per field), yielding a 15-24% performance improvement. The agent identified the bottleneck, explained why it was slow, proposed a fix, and validated the improvement — all within a single chat session.

The .NET team has since contributed pull requests to CsvHelper, NLog, Serilog, and other libraries using insights surfaced by the Profiler Agent.

PerfTips integration: profiling while you debug

The March 2026 update brought one of the most practical additions to the Profiler Agent: integration with debug-time PerfTips.

As you step through code in the debugger, Visual Studio shows execution time and performance signals inline next to each statement. Previously, these were informational only. Now, clicking a PerfTip hands the data to the Profiler Agent. Copilot analyses the elapsed time, CPU usage, and memory behaviour for that specific code path and suggests targeted optimisations on the spot.

This shifts performance analysis from a separate, post-hoc activity into something you do naturally while debugging. You spot a slow line, click the PerfTip, and get an explanation and fix suggestion without leaving the debugger.

ASP.NET Core: .NET Counters analysis

For web applications, the Profiler Agent uses .NET Counters to provide ASP.NET-specific diagnostics. It performs project trait detection — recognising that your project is a web application — and automatically pivots to counters-driven analysis that surfaces issues specific to request processing, middleware pipelines, and connection handling.

This matters because profiling a web application is fundamentally different from profiling a console application. Request throughput, queue depth, and GC pauses during request processing all require different instrumentation than a simple CPU trace. The agent handles this context switch automatically.

Test Explorer integration

You don't need to write benchmarks from scratch. The Profiler Agent can discover existing unit tests or BenchmarkDotNet benchmarks that exercise performance-critical code paths. The March 2026 update added a Profile with Copilot command directly in Test Explorer — select a test, profile it, and let the agent analyse the results.

When no suitable test or benchmark exists, the agent generates a lightweight measurement artefact to capture baseline metrics. This is particularly useful in codebases where performance testing wasn't previously a priority — the agent bootstraps the infrastructure for you.

Benchmarks/OrderProcessingBenchmarks.cs
[MemoryDiagnoser]
public class OrderProcessingBenchmarks
{
    private List<Order> _orders = null!;
    private OrderProcessor _processor = null!;

    [GlobalSetup]
    public void Setup()
    {
        _orders = OrderFixtures.Generate(count: 10_000);
        _processor = new OrderProcessor(new InMemoryRepository());
    }

    [Benchmark(Baseline = true)]
    public async Task ProcessOrders_Original()
    {
        foreach (var order in _orders)
        {
            await _processor.ProcessAsync(order);
        }
    }

    [Benchmark]
    public async Task ProcessOrders_Batched()
    {
        await _processor.ProcessBatchAsync(_orders);
    }
}

The agent generates benchmarks like this tailored to your actual code, not generic templates. It reads your project structure, understands your types, and produces something that compiles and runs.

What it handles well — and where it falls short

The Profiler Agent excels at a specific class of performance problems:

Where it struggles is the same territory that challenges any automated tool:

Use it as an accelerator for the profiling work you'd do anyway, not as a replacement for understanding your system's architecture.

Common pitfalls

Treating it as an oracle. The agent's suggestions are informed by real profiling data, but they're still suggestions. Always review the generated code and understand the tradeoff before accepting changes.

Ignoring the validation step. The agent's workflow includes re-running benchmarks after applying fixes. If you skip this step — accepting the code change without confirming the improvement — you lose the main advantage over simply asking Copilot Chat for performance advice.

Forgetting about production context. A BenchmarkDotNet result on your development machine doesn't account for production load, memory pressure, or GC behaviour under concurrent requests. The agent helps you find and fix bottlenecks locally, but you still need production profiling and monitoring.

Over-optimising stable code. The agent makes it easy to chase micro-optimisations. A 15% improvement in a method that runs once at startup is meaningless. Focus the agent on hot paths that actually affect user experience or throughput.

Not using AsNoTracking() when the agent suggests it. This is the single most common EF Core performance fix the agent surfaces. If you're querying data for read-only display, there's no reason to track entities. The agent catches this reliably.

Summary