Kestrel is the heart of ASP.NET Core — a fast, cross-platform, and lightweight web server built for modern cloud-native applications. Whether you’re deploying on Windows, Linux, or Docker, Kestrel powers your app behind the scenes.
Let’s explore what Kestrel is, how it works internally, how to configure and deploy it (with IIS or Nginx reverse proxy setups), and end with key interview questions developers must know. 🚀
🧩 Introduction
🔹 What is Kestrel Web Server?
Kestrel is the cross-platform web server that comes built-in with ASP.NET Core. It’s designed to:
Serve HTTP requests directly using managed code.
Run on Windows, Linux, and macOS.
Deliver high performance using asynchronous I/O.
Integrate seamlessly with reverse proxies such as IIS, Nginx, or Apache.
💡 Why Kestrel?
Before .NET Core, applications ran exclusively on IIS. But .NET Core’s goal was cross-platform flexibility — hence Kestrel became the default server for all ASP.NET Core applications.
⚙️ Architecture Overview
Kestrel uses:
Managed sockets (previously
libuvfor cross-platform I/O).A highly optimized request/response pipeline built on top of
System.IO.Pipelines.Asynchronous task-based I/O for non-blocking performance.
Connection middleware to support protocols (HTTP/1.x, HTTP/2, and HTTP/3 with QUIC).
Kestrel can handle millions of concurrent requests efficiently — making it ideal for microservices, APIs, and real-time applications.
🔍 How Kestrel Works (Internals)
Kestrel sits at the bottom of the ASP.NET Core pipeline. Here’s how it processes each request:
Socket Listener — Listens on configured IP/Port using managed sockets.
HTTP Parser — Reads request headers, validates the HTTP method and version.
Request Pipeline — Passes the request into ASP.NET Core middleware (like routing, authentication, controllers).
Response Writer — Writes the response stream back to the network layer asynchronously.
🧠 Thread & Connection Management
Uses async/await to free up threads for other I/O operations.
Each connection runs in a lightweight loop that handles multiple requests efficiently.
Supports limits like:
MaxConcurrentConnectionsMaxConcurrentUpgradedConnectionsMaxRequestBodySize
💻 Real-World Example: Hosting a .NET 8 Web API using Kestrel
Let’s create a simple .NET 8 Web API for a matrimonial platform, SoulMateSpot, hosted via Kestrel.
Program.cs
var builder = WebApplication.CreateBuilder(args);
// Configure Kestrel
builder.WebHost.ConfigureKestrel(options =>
{
options.Limits.MaxConcurrentConnections = 100;
options.Limits.MaxRequestBodySize = 10 * 1024; // 10 KB
options.ListenAnyIP(5000); // HTTP
options.ListenAnyIP(5001, listenOptions =>
{
listenOptions.UseHttps("certificate.pfx", "password");
});
});
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
appsettings.json
{"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://0.0.0.0:5000"
},
"Https": {
"Url": "https://0.0.0.0:5001",
"Certificate": {
"Path": "certificate.pfx",
"Password": "password"
}
}
},
"Limits": {
"MaxConcurrentConnections": 100,
"MaxRequestBodySize": 10485760
}}}🧭 Deployment Scenarios
1️⃣ Using Kestrel Alone (for Internal APIs or Microservices)
When you host in Docker or behind a service mesh (like Kubernetes or Azure AKS), Kestrel can serve traffic directly on internal ports.
2️⃣ Using Kestrel Behind Reverse Proxy (for Public Web Apps)
For production-grade web apps, always run Kestrel behind IIS (Windows) or Nginx (Linux) to improve:
Security (firewall + SSL termination)
Logging
Load balancing
Static file handling
🔁 Reverse Proxy Setup
⚠️ Why Not Expose Kestrel Directly?
Kestrel is powerful but not hardened for the public internet.
It doesn’t include:
Full request filtering
DDOS protection
Advanced logging & buffering
Hence, Microsoft recommends using a reverse proxy in front of Kestrel.
🪟 IIS Reverse Proxy (Windows Server)
1️⃣ Install Hosting Bundle on the server (includes ANCM).
2️⃣ Publish your app:
dotnet publish -c Release
3️⃣ Host in IIS:
Create a new site → point to published folder.
In
web.config:
<aspNetCore processPath="dotnet" arguments="YourApp.dll" hostingModel="OutOfProcess" />
Flow:
🌐 Browser → IIS → ASP.NET Core Module (ANCM) → Kestrel → Application
🐧 Nginx Reverse Proxy (Linux)
1️⃣ Install Nginx:
sudo apt install nginx
2️⃣ Configure proxy:
sudo nano /etc/nginx/sites-available/default
3️⃣ Add:
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
4️⃣ Restart:
sudo systemctl restart nginx
Flow:
🌐 Browser → Nginx → Kestrel → .NET App

Join the conversation! Your thoughts help the community grow.