Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Introduction
.NET 8 introduced the Request Timeouts Middleware to enable configuring request timeouts globally as well as per endpoint. This functionality is also available in YARP 2.1 when running on .NET 8 or newer.
Defaults
Requests do not have any timeouts by default, other than the ActivityTimeout used to clean up idle requests. A default policy specified in RequestTimeoutOptions will apply to proxied requests as well.
Interaction with ActivityTimeout
Both route-level Timeout and cluster-level ActivityTimeout apply to proxied requests. Understanding how they interact is important for configuring appropriate timeouts:
ActivityTimeout is configured per cluster in the
HttpRequestsection and has a default value of 100 seconds. This timeout resets whenever there's activity on the request. Activity includes receiving response headers or successfully reading or writing request, response, or streaming data (like gRPC or WebSockets). TCP keep-alives and HTTP/2 protocol pings do not reset the timeout, but WebSocket pings do.Timeout is configured per route and specifies the total time allowed for a request to complete.
Which timeout takes precedence?
Both timeouts apply simultaneously. If a request is idle (no activity), the ActivityTimeout will cancel it. If a request is active but taking too long overall, the route-level Timeout will cancel it. In practice, for an idle request, whichever timeout is lower will take effect first.
For example:
- With a route
Timeoutof 300 seconds and the defaultActivityTimeoutof 100 seconds: if the request becomes idle, it will be canceled after 100 seconds due toActivityTimeout, even though the route allows up to 300 seconds. - With a route
Timeoutof 60 seconds and the defaultActivityTimeoutof 100 seconds: the request will be canceled after 60 seconds if it hasn't completed, regardless of activity.
Debugging considerations
An important difference between these timeouts:
- Route-level Timeout does not apply when a debugger is attached to the process, making it easier to debug long-running requests.
- ActivityTimeout always applies, even when a debugger is attached.
To avoid ActivityTimeout interfering with debugging or legitimate long-running requests, configure it explicitly in the cluster's HttpRequest section:
{
"Clusters": {
"cluster1": {
"HttpRequest": {
"ActivityTimeout": "00:10:00"
},
"Destinations": {
"cluster1/destination1": {
"Address": "https://localhost:10001/"
}
}
}
}
}
Configuration
Timeouts and Timeout Policies can be specified per route via RouteConfig and can be bound from the Routes sections of the config file. As with other route properties, this can be modified and reloaded without restarting the proxy. Policy names are case insensitive.
Timeouts are specified in a TimeSpan format (HH:MM:SS). Specifying both a Timeout and a TimeoutPolicy on the same route is invalid and will cause the configuration to be rejected.
Note that request timeouts do not apply when a debugger is attached to the process.
Example:
{
"ReverseProxy": {
"Routes": {
"route1" : {
"ClusterId": "cluster1",
"TimeoutPolicy": "customPolicy",
"Match": {
"Hosts": [ "localhost" ]
}
}
"route2" : {
"ClusterId": "cluster1",
"Timeout": "00:01:00",
"Match": {
"Hosts": [ "localhost2" ]
}
}
},
"Clusters": {
"cluster1": {
"Destinations": {
"cluster1/destination1": {
"Address": "https://localhost:10001/"
}
}
}
}
}
}
Timeout policies and the default policy can be configured in the service collection and the middleware can be added as follows:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddReverseProxy()
.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
builder.Services.AddRequestTimeouts(options =>
{
options.AddPolicy("customPolicy", TimeSpan.FromSeconds(20));
});
var app = builder.Build();
app.UseRequestTimeouts();
app.MapReverseProxy();
app.Run();
Disable timeouts
Specifying the value disable in a route's TimeoutPolicy parameter means the request timeout middleware will not apply timeouts to this route.
WebSockets
Request timeouts are disabled after the initial WebSocket handshake. However, ActivityTimeout does apply to WebSocket requests. WebSocket keep-alives can be enabled by either the client or server talking to the proxy to keep the connection from becoming idle and triggering the ActivityTimeout.
ASP.NET Core