diff --git a/build/cSpell.json b/build/cSpell.json
index 6bdc2226cc..42795c7a70 100644
--- a/build/cSpell.json
+++ b/build/cSpell.json
@@ -12,6 +12,7 @@
"Cygwin",
"Diagnoser",
"diagnosers",
+ "diagsession",
"disassemblers",
"disassm",
"Jits",
@@ -29,6 +30,7 @@
"Pseudocode",
"runtimes",
"Serilog",
+ "vsprofiler",
"vstest",
"Tailcall",
"toolchains",
diff --git a/docs/articles/features/toc.yml b/docs/articles/features/toc.yml
index ac29397743..61e3a2cd54 100644
--- a/docs/articles/features/toc.yml
+++ b/docs/articles/features/toc.yml
@@ -12,5 +12,7 @@
href: etwprofiler.md
- name: EventPipeProfiler
href: event-pipe-profiler.md
+- name: VSProfiler
+ href: vsprofiler.md
- name: VSTest
href: vstest.md
\ No newline at end of file
diff --git a/docs/articles/features/vsprofiler.md b/docs/articles/features/vsprofiler.md
new file mode 100644
index 0000000000..9e8f52712d
--- /dev/null
+++ b/docs/articles/features/vsprofiler.md
@@ -0,0 +1,71 @@
+---
+uid: docs.vsprofiler
+name: VS Profiler
+---
+
+# Running with Visual Studio profiler
+Visual Studio supports [profiler integration with BenchmarkDotNet](https://learn.microsoft.com/visualstudio/profiling/profiling-with-benchmark-dotnet) on Windows through its [Microsoft.VisualStudio.BenchmarkDotNetDiagnosers](https://www.nuget.org/packages/Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers) NuGet package. Once installed, Visual Studio specific diagnosers will capture performance data in runs and automatically open traces if launched through Visual Studio
+
+
+
+## How it works
+
+First, install the [Microsoft.VisualStudio.BenchmarkDotNetDiagnosers](https://www.nuget.org/packages/Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers) NuGet package in your benchmarking project. Next add one or more of the Visual Studio diagnosers to your benchmark to capture the relevant profiling information while benchmarking. Lastly, run your benchmarks and a diagsession will be generated. If run from Visual Studio the diagsession will automatically be opened.
+
+## Available Diagnosers
+
+* `[CPUUsageDiagnoser]` - Enables the [CPU Usage tool](https://learn.microsoft.com/visualstudio/profiling/cpu-usage).
+* `[DatabaseDiagnoser]` - Enables the [Database tool](https://learn.microsoft.com/visualstudio/profiling/analyze-database)
+* `[DotNetCountersDiagnoser]` - Enables the [.NET Counters tool](https://learn.microsoft.com/visualstudio/profiling/dotnet-counters-tool)
+* `[DotNetObjectAllocDiagnoser]` - Enables the [.NET Object Allocation tool](https://learn.microsoft.com/visualstudio/profiling/dotnet-alloc-tool). When using this tool, you must also specify `[DotNetObjectAllocJobConfiguration]` on the benchmark. If this is missing the run will fail and you will receive an error indicating you need to add it.
+* `[EventsDiagnoser]` - Enables the [Events tool](https://learn.microsoft.com/visualstudio/profiling/events-viewer)
+* `[FileIODiagnoser]` - Enables the [File IO tool](https://learn.microsoft.com/visualstudio/profiling/use-file-io)
+
+## How to use it?
+
+After installing the [Microsoft.VisualStudio.BenchmarkDotNetDiagnosers](https://www.nuget.org/packages/Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers) NuGet package add the following code as a benchmark:
+
+```cs
+using System;
+using System.Security.Cryptography;
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Running;
+using Microsoft.VSDiagnostics;
+
+namespace MyBenchmarks
+{
+ [CPUUsageDiagnoser]
+ public class Md5VsSha256
+ {
+ private const int N = 10000;
+ private readonly byte[] data;
+
+ private readonly SHA256 sha256 = SHA256.Create();
+ private readonly MD5 md5 = MD5.Create();
+
+ public Md5VsSha256()
+ {
+ data = new byte[N];
+ new Random(42).NextBytes(data);
+ }
+
+ [Benchmark]
+ public byte[] Sha256() => sha256.ComputeHash(data);
+
+ [Benchmark]
+ public byte[] Md5() => md5.ComputeHash(data);
+ }
+
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ var summary = BenchmarkRunner.Run(typeof(Program).Assembly);
+ }
+ }
+}
+```
+
+In this case we have added the `[CpuUsageDiagnoser]` to capture a CPU sampling trace. From here run the benchmark in Visual Studio (Ctrl+F5), and after the benchmark run the resulting diagsession will be displayed. Double clicking on one of the benchmark rows shown under the Benchmarks tab will filter the time selection to the specific benchmark allowing you to better isolate and investigate.
+
+
\ No newline at end of file
diff --git a/docs/articles/samples/IntroVisualStudioProfiler.md b/docs/articles/samples/IntroVisualStudioProfiler.md
new file mode 100644
index 0000000000..8d35498f21
--- /dev/null
+++ b/docs/articles/samples/IntroVisualStudioProfiler.md
@@ -0,0 +1,23 @@
+---
+uid: BenchmarkDotNet.Samples.IntroVisualStudioProfiler
+---
+
+## Sample: Visual Studio Profiler
+
+Using the [Microsoft.VisualStudio.BenchmarkDotNetDiagnosers](https://www.nuget.org/packages/Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers) NuGet package you can capture performance profiles of your benchmarks that can be opened in Visual Studio.
+
+### Source code
+
+[!code-csharp[IntroVisualStudioDiagnoser.cs](../../../samples/BenchmarkDotNet.Samples/IntroVisualStudioDiagnoser.cs)]
+
+### Output
+The output will contain a path to the collected diagsession and automatically open in Visual Studio when launched from it.
+
+```markdown
+// * Diagnostic Output - VSDiagnosticsDiagnoser *
+Collection result moved to 'C:\Work\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\net8.0\BenchmarkDotNet.Artifacts\BenchmarkDotNet_IntroVisualStudioProfiler_20241205_192056.diagsession'.
+Session : {d54ebddb-2d6d-404f-b1da-10acbc89635f}
+ Stopped
+Exported diagsession file: C:\Work\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\net8.0\BenchmarkDotNet.Artifacts\BenchmarkDotNet_IntroVisualStudioProfiler_20241205_192056.diagsession.
+Opening diagsession in VisualStudio: 15296
+```
\ No newline at end of file
diff --git a/docs/articles/samples/toc.yml b/docs/articles/samples/toc.yml
index 7e4c7671e1..b9a1c45bf1 100644
--- a/docs/articles/samples/toc.yml
+++ b/docs/articles/samples/toc.yml
@@ -124,6 +124,8 @@
href: IntroTagColumn.md
- name: IntroTailcall
href: IntroTailcall.md
+- name: IntroVisualStudioProfiler
+ href: IntroVisualStudioProfiler.md
- name: IntroWasm
href: IntroWasm.md
- name: IntroUnicode
diff --git a/docs/images/vs-profiler-demo.png b/docs/images/vs-profiler-demo.png
new file mode 100644
index 0000000000..928f012df1
Binary files /dev/null and b/docs/images/vs-profiler-demo.png differ
diff --git a/samples/BenchmarkDotNet.Samples/BenchmarkDotNet.Samples.csproj b/samples/BenchmarkDotNet.Samples/BenchmarkDotNet.Samples.csproj
index 36c3f60b32..7cdc359d7d 100644
--- a/samples/BenchmarkDotNet.Samples/BenchmarkDotNet.Samples.csproj
+++ b/samples/BenchmarkDotNet.Samples/BenchmarkDotNet.Samples.csproj
@@ -23,6 +23,8 @@
+
+
diff --git a/samples/BenchmarkDotNet.Samples/IntroVisualStudioDiagnoser.cs b/samples/BenchmarkDotNet.Samples/IntroVisualStudioDiagnoser.cs
new file mode 100644
index 0000000000..e513f39320
--- /dev/null
+++ b/samples/BenchmarkDotNet.Samples/IntroVisualStudioDiagnoser.cs
@@ -0,0 +1,23 @@
+using System;
+using BenchmarkDotNet.Attributes;
+using Microsoft.VSDiagnostics;
+
+namespace BenchmarkDotNet.Samples
+{
+ // Enables profiling with the CPU Usage tool
+ // See: https://learn.microsoft.com/visualstudio/profiling/profiling-with-benchmark-dotnet
+ [CPUUsageDiagnoser]
+ public class IntroVisualStudioProfiler
+ {
+ private readonly Random rand = new Random(42);
+
+ [Benchmark]
+ public void BurnCPU()
+ {
+ for (int i = 0; i < 100000; ++i)
+ {
+ rand.Next(1, 100);
+ }
+ }
+ }
+}
\ No newline at end of file