Skip to main content

ASP.NET Benchmarks

The ASP.NET benchmarks measure the throughput and latency of ASP.NET Kestrel web applications under sustained HTTP load. The workloads use a client-server architecture where the server runs an ASP.NET application and the client generates HTTP requests using Bombardier or Wrk.

Two server workloads are supported:

  • TechEmpower JSON Serialization — Based on the ASP.NET Benchmarks project (derived from the TechEmpower framework), the server exposes a /json endpoint that serializes a simple JSON object. Supports Bombardier and Wrk as client load generators.
  • OrchardCore CMS — Runs the OrchardCore content management system with a Blog recipe, benchmarked with Wrk against the /about endpoint.

Both server configurations support CPU core affinity via the BindToCores and CoreAffinity parameters, allowing the server process to be pinned to specific CPU cores for controlled performance measurement.

Deployment Modes

The ASP.NET benchmark workloads support two deployment modes:

  • Multi-VM (Client-Server) — The server and client run on separate machines connected via an environment layout file. This is the recommended mode for production benchmarking as it isolates server and client resource consumption.
  • Single-VM — When no layout file is provided, both server and client actions run sequentially on the same machine. The client connects to the server via the loopback address (127.0.0.1). This mode is useful for development, validation, and quick smoke testing.

CPU core affinity profiles (e.g., PERF-WEB-ASPNET-WRK-AFFINITY.json) work in both modes. In single-VM mode, core affinity is especially useful to prevent the server and client from contending for the same CPU cores.

What is Being Measured?

The client tools (Bombardier or Wrk) generate concurrent HTTP requests against the ASP.NET server and capture latency percentile distributions and throughput statistics.

TechEmpower JSON Serialization

The server exposes a /json endpoint that serializes a simple JSON object. This scenario measures raw HTTP request processing performance of the Kestrel server with minimal application logic overhead.

OrchardCore CMS

The server runs a full OrchardCore CMS application with a Blog recipe. The /about endpoint exercises the full CMS rendering pipeline including routing, middleware, and content rendering.

Workload Metrics

The following metrics are examples of those captured by the Virtual Client when running the ASP.NET benchmark workloads.

Bombardier Metrics

When Bombardier is used as the client (e.g., PERF-WEB-ASPNET-BOMBARDIER.json):

NameExample ValueUnitDescription
Latency Average133.3698688millisecondsAverage HTTP response latency
Latency Max7123.06304millisecondsMaximum HTTP response latency
Latency P5083.39392millisecondsHTTP response latency (50th percentile)
Latency P75160.14336millisecondsHTTP response latency (75th percentile)
Latency P90286.4128millisecondsHTTP response latency (90th percentile)
Latency P95367.4112millisecondsHTTP response latency (95th percentile)
Latency P99637.534208millisecondsHTTP response latency (99th percentile)
RequestPerSecond Avg32768.449018Reqs/secASP.NET Web Requests per second (average)
RequestPerSecond Stddev6446.822354105378Reqs/secASP.NET Web Requests per second (standard deviation)
RequestPerSecond P5031049.462844Reqs/secASP.NET Web Requests per second (P50)
RequestPerSecond P7535597.436614Reqs/secASP.NET Web Requests per second (P75)
RequestPerSecond P9039826.205746Reqs/secASP.NET Web Requests per second (P90)
RequestPerSecond P9541662.542962Reqs/secASP.NET Web Requests per second (P95)
RequestPerSecond P9948600.556224Reqs/secASP.NET Web Requests per second (P99)

Wrk Metrics

When Wrk is used as the client (e.g., PERF-WEB-ASPNET-WRK.json, PERF-WEB-ASPNET-ORCHARD-WRK.json):

NameExample ValueUnitDescription
latency_p501.427millisecondsHTTP response latency (50th percentile)
latency_p751.982millisecondsHTTP response latency (75th percentile)
latency_p902.683millisecondsHTTP response latency (90th percentile)
latency_p993.960millisecondsHTTP response latency (99th percentile)
latency_p99_96.930millisecondsHTTP response latency (99.9th percentile)
latency_p1009.770millisecondsHTTP response latency (100th percentile)
requests/sec16305.17requests/secAggregate throughput
transfers/sec20.01megabytes/secData transfer rate

See the Wrk/Wrk2 documentation and Bombardier documentation for the complete list of client metrics.

Profiles

The following profiles are available for the ASP.NET benchmark workloads. See the profile details page for per-profile parameters, dependencies, and usage examples.

Profile NameDescriptionClient ToolServerPlatforms
PERF-WEB-ASPNET-WRK.jsonTechEmpower JSON serialization benchmark using Wrk with warm-up pass.WrkExecutorAspNetServerExecutorlinux-x64, linux-arm64, win-x64, win-arm64
PERF-WEB-ASPNET-WRK-AFFINITY.jsonTechEmpower JSON serialization benchmark using Wrk with CPU core affinity.WrkExecutorAspNetServerExecutorlinux-x64, linux-arm64, win-x64, win-arm64
PERF-WEB-ASPNET-BOMBARDIER.jsonTechEmpower JSON serialization benchmark using Bombardier with 256 connections.BombardierExecutorAspNetServerExecutorlinux-x64, linux-arm64, win-x64, win-arm64
PERF-WEB-ASPNET-ORCHARD-WRK.jsonOrchardCore CMS benchmark using Wrk with warm-up pass.WrkExecutorAspNetOrchardServerExecutorlinux-x64, linux-arm64

Server Parameters

The following tables describe the key parameters supported by the ASP.NET server executors.

AspNetServerExecutor

ParameterDescriptionDefault
PackageNameThe name of the ASP.NET Benchmarks dependency package.required
DotNetSdkPackageNameThe name of the .NET SDK dependency package.dotnetsdk
TargetFrameworkThe .NET target framework (e.g., net8.0, net9.0).required
ServerPortThe port the Kestrel server listens on.9876
AspNetCoreThreadCountThe ASPNETCORE thread count environment variable.1
DotNetSystemNetSocketsThreadCountThe DOTNET_SYSTEM_NET_SOCKETS_THREAD_COUNT environment variable.1
BindToCoresWhen true, the server process is pinned to specific CPU cores.false
CoreAffinityCPU core affinity specification (e.g., 0-7). Required when BindToCores is true.none

AspNetOrchardServerExecutor

ParameterDescriptionDefault
PackageNameThe name of the OrchardCore dependency package.required
DotNetSdkPackageNameThe name of the .NET SDK dependency package.dotnetsdk
TargetFrameworkThe .NET target framework (e.g., net9.0).required
ServerPortThe port the OrchardCore server listens on.5014
BindToCoresWhen true, the server process is pinned to specific CPU cores.false
CoreAffinityCPU core affinity specification (e.g., 0-7). Required when BindToCores is true.none

Packaging and Setup

The following section covers how to create the custom Virtual Client dependency packages required to execute the workload and toolset(s). This section is meant to provide guidance for users who would like to create their own packages with the software for use with the Virtual Client. For example, users may want to bring in new versions of the software. See the documentation on Dependency Packages for more information on the concepts.

TechEmpower JSON Serialization Setup

  1. Virtual Client installs the .NET SDK via the DotNetInstallation dependency.
  2. Virtual Client clones the ASP.NET Benchmarks GitHub repository.
  3. The src/Benchmarks project is built using dotnet build.
  4. The server is started using dotnet run:
dotnet <path_to_binary>/Benchmarks.dll \
--nonInteractive true \
--scenarios json \
--urls http://*:9876 \
--server Kestrel \
--kestrelTransport Sockets \
--protocol http \
--header "Accept: application/json,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7" \
--header "Connection: keep-alive"
  1. The client tool (Bombardier or Wrk) generates HTTP load against the server:
# Bombardier example
bombardier -d 15s -c 256 -t 2s --fasthttp --insecure -l http://<server_ip>:9876/json --print r --format json

# Wrk example
wrk --latency --threads 64 --connections 4096 --duration 15s --timeout 10s http://<server_ip>:9876/json

OrchardCore CMS Setup

  1. Virtual Client installs the .NET SDK via the DotNetInstallation dependency.
  2. Virtual Client clones the OrchardCore GitHub repository.
  3. The OrchardCore.Cms.Web project is published using dotnet publish.
  4. The server is started:
nohup <path_to_publish>/OrchardCore.Cms.Web --urls http://*:5014
  1. Wrk generates HTTP load against the /about endpoint:
wrk -t 64 -c 128 -d 20s http://<server_ip>:5014/about