You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: aspnetcore/fundamentals/servers/yarp/timeouts.md
+44-3Lines changed: 44 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@ title: YARP Request Timeouts
4
4
description: YARP Request Timeouts
5
5
author: wadepickett
6
6
ms.author: wpickett
7
-
ms.date: 2/6/2025
7
+
ms.date: 11/01/2025
8
8
ms.topic: article
9
9
content_well_notification: AI-contribution
10
10
ai-usage: ai-assisted
@@ -17,7 +17,48 @@ ai-usage: ai-assisted
17
17
.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.
18
18
19
19
## 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
+
```
21
62
22
63
## Configuration
23
64
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
86
127
87
128
### WebSockets
88
129
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