A minimal ASP.NET Core app serves ~1.8x fewer requests/sec on .NET 11 preview 7 than on .NET 10.
Source
webbench.cs (file-based app, no project file):
#:sdk Microsoft.NET.Sdk.Web
var builder = WebApplication.CreateSlimBuilder(args);
builder.Logging.SetMinimumLevel(LogLevel.Warning);
var app = builder.Build();
app.MapGet("/", () => "Hello, World!");
app.Run();
Script
run.sh:
#!/bin/bash
SDKS=${SDKS:-"net10 net11"}
MODES=${MODES:-"jit aot"}
SDK_ROOT=${SDK_ROOT:-$HOME/sdks}
OUT=${OUT:-/tmp/aspnet-repro-out}
BUILD=${BUILD:-1}
URL=http://127.0.0.1:5111
set -e
cd "$(cd "$(dirname "$0")" && pwd)"
trap 'kill $PID 2>/dev/null || true' EXIT
build() {
local props="-p:PublishAot=false"
[ "$2" = aot ] && props="-p:PublishAot=true -p:IlcInstructionSet=native"
rm -rf "$HOME/.local/share/dotnet/runfile/webbench-"*
DOTNET_ROOT="$SDK_ROOT/$1" PATH="$SDK_ROOT/$1:$PATH" \
dotnet publish webbench.cs -c Release -r linux-x64 --self-contained $props -o "$OUT/$1-$2" -v q --nologo >/dev/null
}
run() {
ASPNETCORE_URLS=$URL taskset -c 0-7 "$1/webbench" >/dev/null 2>&1 &
PID=$!
for _ in $(seq 1 100); do curl -sf -o /dev/null $URL && break; sleep 0.2; done
taskset -c 16-23 bombardier -c 32 -d 5s $URL >/dev/null 2>&1
taskset -c 16-23 bombardier -c 32 -d 10s $URL 2>&1 | awk '/Reqs\/sec/{print $2}'
kill $PID; wait $PID 2>/dev/null || true
sleep 1
}
if [ "$BUILD" = 1 ]; then
rm -rf "$OUT"; mkdir -p "$OUT"
for s in $SDKS; do for m in $MODES; do build "$s" "$m"; done; done
fi
printf "%-8s %12s %12s\n" sdk "JIT rps" "NAOT rps"
for s in $SDKS; do
j=""; a=""
for m in $MODES; do r=$(run "$OUT/$s-$m"); [ "$m" = jit ] && j=$r || a=$r; done
printf "%-8s %12s %12s\n" "$s" "$j" "$a"
done
Results
Median of 3 runs, requests/sec:
| SDK |
JIT RPS |
NAOT RPS |
| 10.0.11 |
326,676 |
188,161 |
| 11.0.0-preview.7.26381.103 |
177,858 |
176,568 |
- JIT regressed by 45.6% in .NET 11.
- NAOT was 42.4% slower than JIT in .NET 10.
Environment
- Linux x64 (WSL2, Ubuntu 24.04), 32 logical cores
- Server pinned to cores 0-7, load generator pinned to cores 16-23
- For faster warmup, I recommend disabling Hill Climbing and Tiered Compilation
Prerequisites:
curl -sSL -o dotnet-install.sh https://dot.net/v1/dotnet-install.sh && chmod +x dotnet-install.sh
./dotnet-install.sh --channel 10.0 --install-dir $HOME/sdks/net10 --no-path
./dotnet-install.sh --version 11.0.100-preview.7.26381.103 --install-dir $HOME/sdks/net11 --no-path
curl -sSL -o ~/bin/bombardier https://github.com/codesenberg/bombardier/releases/download/v1.2.6/bombardier-linux-amd64
chmod +x ~/bin/bombardier
A minimal ASP.NET Core app serves ~1.8x fewer requests/sec on .NET 11 preview 7 than on .NET 10.
Source
webbench.cs(file-based app, no project file):Script
run.sh:Results
Median of 3 runs, requests/sec:
Environment
Prerequisites: