diff --git a/test/Benchmarks/Benchmarks.csproj b/test/Benchmarks/Benchmarks.csproj
index 7eef5572a..810986862 100644
--- a/test/Benchmarks/Benchmarks.csproj
+++ b/test/Benchmarks/Benchmarks.csproj
@@ -18,7 +18,18 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Benchmarks/Helper/LocalServer.cs b/test/Benchmarks/Helper/LocalServer.cs
new file mode 100644
index 000000000..802987965
--- /dev/null
+++ b/test/Benchmarks/Helper/LocalServer.cs
@@ -0,0 +1,83 @@
+//
+// Copyright The OpenTelemetry Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#if NETCOREAPP
+
+using System;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using OpenTelemetry;
+using OpenTelemetry.Trace;
+
+namespace Benchmarks.Helper
+{
+ public class LocalServer : IDisposable
+ {
+ private readonly IWebHost host;
+ private TracerProvider tracerProvider;
+
+ public LocalServer(string url, bool enableTracerProvider = false)
+ {
+ void ConfigureTestServices(IServiceCollection services)
+ {
+ if (enableTracerProvider)
+ {
+ this.tracerProvider = Sdk.CreateTracerProviderBuilder()
+ .AddAspNetCoreInstrumentation()
+ .Build();
+ }
+ }
+
+ this.host = new WebHostBuilder()
+ .UseKestrel()
+ .UseStartup()
+ .UseUrls(url)
+ .ConfigureServices(configure => ConfigureTestServices(configure))
+ .Build();
+
+ Task.Run(() => this.host.Run());
+ }
+
+ public void Dispose()
+ {
+ try
+ {
+ this.tracerProvider.Dispose();
+ this.host.Dispose();
+ }
+ catch (Exception)
+ {
+ // ignored, see https://github.com/aspnet/KestrelHttpServer/issues/1513
+ // Kestrel 2.0.0 should have fix it, but it does not seem important for our tests
+ }
+ }
+
+ private class Startup
+ {
+ public void Configure(IApplicationBuilder app)
+ {
+ app.Run(async (context) =>
+ {
+ await context.Response.WriteAsync("Hello World!");
+ });
+ }
+ }
+ }
+}
+#endif
diff --git a/test/Benchmarks/Instrumentation/InstrumentedAspNetCoreBenchmark.cs b/test/Benchmarks/Instrumentation/InstrumentedAspNetCoreBenchmark.cs
new file mode 100644
index 000000000..c373814ed
--- /dev/null
+++ b/test/Benchmarks/Instrumentation/InstrumentedAspNetCoreBenchmark.cs
@@ -0,0 +1,56 @@
+//
+// Copyright The OpenTelemetry Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#if !NETFRAMEWORK
+using System.Net.Http;
+using System.Threading.Tasks;
+using BenchmarkDotNet.Attributes;
+using Benchmarks.Helper;
+
+namespace Benchmarks.Instrumentation
+{
+ [InProcess]
+ [MemoryDiagnoser]
+ public class InstrumentedAspNetCoreBenchmark
+ {
+ private const string LocalhostUrl = "http://localhost:5050";
+
+ private HttpClient client;
+ private LocalServer localServer;
+
+ [GlobalSetup]
+ public void GlobalSetup()
+ {
+ this.localServer = new LocalServer(LocalhostUrl, true);
+ this.client = new HttpClient();
+ }
+
+ [GlobalCleanup]
+ public void GlobalCleanup()
+ {
+ this.localServer.Dispose();
+ this.client.Dispose();
+ }
+
+ [Benchmark]
+ public async Task InstrumentedAspNetCoreGetPage()
+ {
+ var httpResponse = await this.client.GetAsync(LocalhostUrl);
+ httpResponse.EnsureSuccessStatusCode();
+ }
+ }
+}
+#endif
diff --git a/test/Benchmarks/Instrumentation/UninstrumentedAspNetCoreBenchmark.cs b/test/Benchmarks/Instrumentation/UninstrumentedAspNetCoreBenchmark.cs
new file mode 100644
index 000000000..f42dc29e2
--- /dev/null
+++ b/test/Benchmarks/Instrumentation/UninstrumentedAspNetCoreBenchmark.cs
@@ -0,0 +1,56 @@
+//
+// Copyright The OpenTelemetry Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#if !NETFRAMEWORK
+using System.Net.Http;
+using System.Threading.Tasks;
+using BenchmarkDotNet.Attributes;
+using Benchmarks.Helper;
+
+namespace Benchmarks.Instrumentation
+{
+ [InProcess]
+ [MemoryDiagnoser]
+ public class UninstrumentedAspNetCoreBenchmark
+ {
+ private const string LocalhostUrl = "http://localhost:5050";
+
+ private HttpClient client;
+ private LocalServer localServer;
+
+ [GlobalSetup]
+ public void GlobalSetup()
+ {
+ this.localServer = new LocalServer(LocalhostUrl);
+ this.client = new HttpClient();
+ }
+
+ [GlobalCleanup]
+ public void GlobalCleanup()
+ {
+ this.client.Dispose();
+ this.localServer.Dispose();
+ }
+
+ [Benchmark]
+ public async Task SimpleAspNetCoreGetPage()
+ {
+ var httpResponse = await this.client.GetAsync(LocalhostUrl);
+ httpResponse.EnsureSuccessStatusCode();
+ }
+ }
+}
+#endif