Mastering Request Timeout Middleware in ASP.NET Core

In the fast-paced world of API development, managing request timeouts effectively is crucial for maintaining a smooth user experience and ensuring robust application performance. Fortunately, ASP.NET Core 8.0 introduced a powerful, out-of-the-box solution: Request Timeout Middleware.

In this blog, we’ll explore what makes this middleware indispensable, how to integrate it into your applications, and the different ways to configure it for maximum flexibility.


What Is Request Timeout Middleware?

The Middleware for Request Timeout provides a simple way to enforce timeouts for HTTP requests. Instead of relying on custom timeout logic, this middleware allows you to implement, configure, and manage timeouts effortlessly as part of your ASP.NET Core application pipeline.

Supported from .NET 8.0 and later, it requires no additional NuGet packages—it’s built right into the framework.


Getting Started with Request Timeout Middleware

Implementing Middleware for Request Timeout is straightforward. Here’s a step-by-step guide:

1. Register the Request Timeout Middleware

Add the middleware in your Program.cs file:

var builder = WebApplication.CreateBuilder(args);

// Add the Middleware
builder.Services.AddRequestTimeouts();

var app = builder.Build();

// Ensure correct pipeline placement
app.UseHttpsRedirection();  
app.UseRequestTimeout();

app.Run();

📌 Note: Place UseRequestTimeout after UseHttpsRedirection to avoid pipeline conflicts.


2. Configure Timeouts for Endpoints

Request Timeout Middleware supports multiple approaches for applying timeouts:

Minimal API Example

Using the WithRequestTimeout extension method:

app.MapGet("/example", async () =>
{
    await Task.Delay(10000); // Simulate a long-running task
    return Results.Ok("Completed");
}).WithRequestTimeout(TimeSpan.FromSeconds(2));

In this example, if the endpoint doesn’t complete within 2 seconds, it will trigger a timeout.

Controller Example

Apply the [RequestTimeout] attribute directly to your controller methods:

[RequestTimeout(2000)] // Timeout in milliseconds
public async Task<IActionResult> GetExample()
{
    await Task.Delay(10000); // Simulate delay
    return Ok("Completed");
}

3. Global Configuration with Policies

For consistent behavior across multiple endpoints, define and apply timeout policies:

builder.Services.AddRequestTimeouts(options =>
{
    // Default timeout for all endpoints
    options.DefaultPolicy.Timeout = TimeSpan.FromSeconds(1);

    // Named policy for specific use cases
    options.AddPolicy("ShortTimeout", policy =>
    {
        policy.Timeout = TimeSpan.FromSeconds(2);
    });
});

Apply a policy using its name:

[RequestTimeout(Policy = "ShortTimeout")]
public async Task<IActionResult> GetExample()
{
    await Task.Delay(10000); // Simulate delay
    return Ok("Completed");
}

Key Benefits of Request Timeout Middleware

  1. Improved User Experience: Avoid indefinite waits for users by enforcing timeouts with meaningful error responses.
  2. Seamless Integration: The middleware integrates into the ASP.NET Core pipeline, requiring minimal configuration.
  3. Flexibility: Configure default, endpoint-specific, or global timeout policies.

Advanced Configurations

Custom Error Responses

You can customize the error response for timed-out requests:

builder.Services.AddRequestTimeouts(options =>
{
    options.DefaultPolicy.Timeout = TimeSpan.FromSeconds(1);
    options.DefaultPolicy.OnTimeout = async context =>
    {
        context.Response.StatusCode = StatusCodes.Status504GatewayTimeout;
        await context.Response.WriteAsync("Request timed out. Please try again.");
    };
});

Debug Mode Behavior

Keep in mind that this feature does not trigger in debug mode. Run your application without debugging to test timeout scenarios effectively.


Practical Use Cases

  1. External API Calls: Enforce timeouts for APIs dependent on slow external services.
  2. Database Queries: Prevent hanging requests caused by long-running database queries.
  3. Global Policies: Apply default timeouts across your application for consistency.

Live Demo: Behavior in Action

Let’s put it to the test!

  • A 10-second delay with a 2-second timeout results in a 408 Request Timeout.
  • Switching to a 1-second global default policy triggers faster responses with a 504 Gateway Timeout when custom error handling is added.

These examples showcase how easily this Middleware can enhance the performance and reliability of your APIs.


Conclusion

This feature of .NET 8 is a must-have tool in your ASP.NET Core arsenal. Its simplicity, flexibility, and powerful configuration options make it an excellent choice for managing timeouts in modern web applications.

Whether you need global policies or fine-tuned control for specific endpoints, this middleware ensures a better user experience by preventing excessive waiting times and providing meaningful error handling.

You can check this entire blog in action in the YouTube video here.

Leave a Comment