Skip to content

Commit 748aa64

Browse files
CopilotMihaZupan
andauthored
Document ActivityTimeout interaction with route-level Timeout in YARP (#36287)
* Initial plan * Document ActivityTimeout interaction with route-level Timeout in YARP docs Co-authored-by: MihaZupan <[email protected]> * Improve readability of ActivityTimeout description Co-authored-by: MihaZupan <[email protected]> * Clarify ActivityTimeout applies to WebSocket requests Co-authored-by: MihaZupan <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: MihaZupan <[email protected]>
1 parent 4fe10ae commit 748aa64

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

aspnetcore/fundamentals/servers/yarp/timeouts.md

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: YARP Request Timeouts
44
description: YARP Request Timeouts
55
author: wadepickett
66
ms.author: wpickett
7-
ms.date: 2/6/2025
7+
ms.date: 11/01/2025
88
ms.topic: article
99
content_well_notification: AI-contribution
1010
ai-usage: ai-assisted
@@ -17,7 +17,48 @@ ai-usage: ai-assisted
1717
.NET 8 introduced the [Request Timeouts Middleware](/aspnet/core/performance/timeouts) 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.
1818

1919
## Defaults
20-
Requests do not have any timeouts by default, other than the [Activity Timeout](xref:fundamentals/servers/yarp/http-client-config#HttpRequest) used to clean up idle requests. A default policy specified in [RequestTimeoutOptions](/dotnet/api/microsoft.aspnetcore.http.timeouts.requesttimeoutoptions) will apply to proxied requests as well.
20+
Requests do not have any timeouts by default, other than the [ActivityTimeout](xref:fundamentals/servers/yarp/http-client-config#HttpRequest) used to clean up idle requests. A default policy specified in [RequestTimeoutOptions](/dotnet/api/microsoft.aspnetcore.http.timeouts.requesttimeoutoptions) will apply to proxied requests as well.
21+
22+
## Interaction with ActivityTimeout
23+
24+
Both route-level `Timeout` and cluster-level `ActivityTimeout` apply to proxied requests. Understanding how they interact is important for configuring appropriate timeouts:
25+
26+
- **ActivityTimeout** is configured per cluster in the `HttpRequest` section 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.
27+
28+
- **Timeout** is configured per route and specifies the total time allowed for a request to complete.
29+
30+
### Which timeout takes precedence?
31+
32+
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.
33+
34+
For example:
35+
- With a route `Timeout` of **300 seconds** and the default `ActivityTimeout` of **100 seconds**: if the request becomes idle, it will be canceled after 100 seconds due to `ActivityTimeout`, even though the route allows up to 300 seconds.
36+
- With a route `Timeout` of **60 seconds** and the default `ActivityTimeout` of **100 seconds**: the request will be canceled after 60 seconds if it hasn't completed, regardless of activity.
37+
38+
### Debugging considerations
39+
40+
An important difference between these timeouts:
41+
- **Route-level Timeout** does not apply when a debugger is attached to the process, making it easier to debug long-running requests.
42+
- **ActivityTimeout** always applies, even when a debugger is attached.
43+
44+
To avoid `ActivityTimeout` interfering with debugging or legitimate long-running requests, configure it explicitly in the cluster's `HttpRequest` section:
45+
46+
```json
47+
{
48+
"Clusters": {
49+
"cluster1": {
50+
"HttpRequest": {
51+
"ActivityTimeout": "00:10:00"
52+
},
53+
"Destinations": {
54+
"cluster1/destination1": {
55+
"Address": "https://localhost:10001/"
56+
}
57+
}
58+
}
59+
}
60+
}
61+
```
2162

2263
## Configuration
2364
Timeouts and Timeout Policies can be specified per route via [RouteConfig](xref:Yarp.ReverseProxy.Configuration.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.
@@ -86,4 +127,4 @@ Specifying the value `disable` in a route's `TimeoutPolicy` parameter means the
86127

87128
### WebSockets
88129

89-
Request timeouts are disabled after the initial WebSocket handshake.
130+
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`.

0 commit comments

Comments
 (0)