YARP (Yet Another Reverse Proxy) is Microsoft's library for building high-performance reverse proxies in .NET. Unlike Nginx or HAProxy, YARP runs inside your ASP.NET Core application, giving you full access to the .NET middleware pipeline for routing, authentication, rate limiting, and request transformation.
Setup
dotnet add package Yarp.ReverseProxy
Configure in Program.cs:
builder.Services.AddReverseProxy()
.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
var app = builder.Build();
app.MapReverseProxy();
app.Run();
Configuration
Define routes and clusters in appsettings.json:
{
"ReverseProxy": {
"Routes": {
"api-route": {
"ClusterId": "api-cluster",
"Match": {
"Path": "/api/{**catch-all}"
}
},
"web-route": {
"ClusterId": "web-cluster",
"Match": {
"Path": "/{**catch-all}"
}
}
},
"Clusters": {
"api-cluster": {
"Destinations": {
"api-1": { "Address": "https://api-server-1:5001" },
"api-2": { "Address": "https://api-server-2:5001" }
},
"LoadBalancingPolicy": "RoundRobin"
},
"web-cluster": {
"Destinations": {
"web-1": { "Address": "https://web-server:5002" }
}
}
}
}
}
Routes match incoming requests by path (and optionally by host, headers, or query parameters). Each route points to a cluster, which contains one or more destination addresses.
Load Balancing Policies
YARP supports several built-in policies:
RoundRobin— distributes requests evenly across destinationsRandom— picks a random destinationLeastRequests— sends to the destination with fewest active requestsPowerOfTwoChoices— picks two random destinations and uses the one with fewer requestsFirstAlphabetical— always picks the first destination (useful for active/passive)
{
"api-cluster": {
"LoadBalancingPolicy": "LeastRequests",
"Destinations": {
"api-1": { "Address": "https://server-1:5001" },
"api-2": { "Address": "https://server-2:5001" },
"api-3": { "Address": "https://server-3:5001" }
}
}
}
Request Transforms
Modify requests as they pass through the proxy:
{
"api-route": {
"ClusterId": "api-cluster",
"Match": { "Path": "/api/{**remainder}" },
"Transforms": [
{ "PathRemovePrefix": "/api" },
{ "RequestHeader": "X-Forwarded-Prefix", "Set": "/api" }
]
}
}
For complex transforms, use code:
builder.Services.AddReverseProxy()
.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"))
.AddTransforms(context =>
{
context.AddRequestTransform(async transformContext =>
{
var token = await GetAccessTokenAsync();
transformContext.ProxyRequest.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", token);
});
});
This injects a bearer token into every proxied request — useful for backend-to-backend authentication.
Health Checks
Configure active health probes:
{
"api-cluster": {
"HealthCheck": {
"Active": {
"Enabled": true,
"Interval": "00:00:30",
"Timeout": "00:00:10",
"Path": "/health"
}
},
"Destinations": {
"api-1": { "Address": "https://server-1:5001" }
}
}
}
YARP periodically calls /health on each destination. Unhealthy destinations are removed from rotation until they recover.
Programmatic Configuration
For dynamic scenarios, load configuration from code instead of JSON:
builder.Services.AddReverseProxy()
.LoadFromMemory(GetRoutes(), GetClusters());
RouteConfig[] GetRoutes() =>
[
new RouteConfig
{
RouteId = "api-route",
ClusterId = "api-cluster",
Match = new RouteMatch { Path = "/api/{**catch-all}" }
}
];
ClusterConfig[] GetClusters() =>
[
new ClusterConfig
{
ClusterId = "api-cluster",
LoadBalancingPolicy = "RoundRobin",
Destinations = new Dictionary<string, DestinationConfig>
{
["api-1"] = new() { Address = "https://server-1:5001" },
["api-2"] = new() { Address = "https://server-2:5001" }
}
}
];
Middleware Integration
Because YARP runs inside ASP.NET Core, you can apply any middleware:
app.UseAuthentication();
app.UseAuthorization();
app.UseRateLimiter();
app.MapReverseProxy(proxyPipeline =>
{
proxyPipeline.UseSessionAffinity();
proxyPipeline.UseLoadBalancing();
proxyPipeline.UsePassiveHealthChecks();
});
This applies authentication and rate limiting before the proxy, then uses YARP's own middleware for session affinity and load balancing.
Use Cases
YARP works well as an API gateway, a BFF (backend for frontend), a migration tool for gradually routing traffic from an old system to a new one, or a development proxy for aggregating multiple microservices behind a single endpoint. Because it's just .NET code, you can add custom logic that would require plugins or scripting in traditional reverse proxies.