Skip to content
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 43 additions & 2 deletions aspnetcore/fundamentals/servers/yarp/timeouts.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: YARP Request Timeouts
description: YARP Request Timeouts
author: wadepickett
ms.author: wpickett
ms.date: 2/6/2025
ms.date: 11/01/2025
ms.topic: article
content_well_notification: AI-contribution
ai-usage: ai-assisted
Expand All @@ -17,7 +17,48 @@ ai-usage: ai-assisted
.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.

## Defaults
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.
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.

## 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 `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.

- **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 `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.
- 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.

### 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:

```json
{
"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](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.
Expand Down