ASP.NET Core 3.1在IIS下性能低于Kestrel的原因问询
Given your scenario—super lightweight endpoint returning a static struct, IIS InProcess hitting half the RPS of Kestrel, and failing to saturate your 32 logical cores on Windows 10 1903—here are the most likely causes to investigate:
Windows 10's Client OS IIS Resource Restrictions
Unlike Windows Server, Windows 10 (a client OS) enforces default CPU throttling and resource limits on IIS to prevent it from hogging system resources meant for user apps. Kestrel, running as a standalone process, isn't subject to these OS-level constraints, so it can freely utilize all available logical processors. This is the top suspect for the CPU saturation gap you're seeing.Conservative IIS App Pool & Thread Pool Configs
IIS application pools come with out-of-the-box settings that are too conservative for high-throughput, multi-core scenarios:- The default CLR thread pool limits might not scale to your 32 logical cores, meaning IIS can't spawn enough worker threads to handle the bombardier load.
- Your app pool might have a low
Queue Lengthsetting, which throttles incoming requests before they even reach your ASP.NET Core code. - Verify the app pool isn't set to 32-bit mode—this would severely limit performance on your 64-bit system, restricting memory access and CPU utilization.
Unnecessary IIS Module Overhead
Even in InProcess mode, IIS routes requests through its native modules (likeStaticFileModule,WindowsAuthenticationModule) before they hit your ASP.NET Core pipeline. These modules add small but cumulative overhead for lightweight requests like yourDummyControllerendpoint. Kestrel's pipeline is far leaner, with no extra IIS modules in the path, allowing it to process requests faster and utilize CPU more efficiently.ASP.NET Core 3.1 InProcess Hosting Limitations
ASP.NET Core 3.1's InProcess hosting had some known edge cases with multi-core CPU utilization, especially on client OSes. Later .NET versions (5+) improved this, but in 3.1, the InProcess host might not distribute work across all logical processors as effectively as Kestrel, which is optimized for parallel request handling out of the box.Windows 10 Network Stack Throttling
Even with loopback requests, Windows 10's network stack might have default throttling for IIS HTTP traffic that doesn't apply to Kestrel. Client OSes prioritize user-facing apps over server workloads, so these limits can cap your throughput even if CPU isn't fully saturated.
Troubleshooting Steps to Validate:
- Adjust IIS App Pool Settings: Switch to 64-bit mode, increase thread pool limits, and raise the
Queue Lengthto match your test load. - Disable Unused IIS Modules: Remove any modules your app doesn't need (e.g., authentication modules if you're using anonymous access) to reduce pipeline overhead.
- Test on Windows Server: If possible, run the same test on a Windows Server machine—this will eliminate client OS resource restrictions and confirm if that's the root cause.
- Profile CPU Usage: Use tools like PerfView to profile both the
w3wpprocess (IIS InProcess) and your standalone Kestrel process. Look for bottlenecks like thread pool starvation or excessive module processing time in IIS.
内容的提问来源于stack exchange,提问作者G S




