Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
9c2e962
initial version of the http latency tags docs
rainsxng Sep 29, 2025
08b9b97
update latency docs
rainsxng Sep 29, 2025
8762125
fix linter
rainsxng Sep 29, 2025
95129ee
fix lint
rainsxng Sep 29, 2025
c021d22
add toc entry
rainsxng Sep 30, 2025
d26dd4d
update text and formatting
rainsxng Oct 9, 2025
9a8b0ff
update docs to include correct samples and tables
rainsxng Oct 9, 2025
998c825
Merge branch 'main' into dbohdanov/latency-tags
rainsxng Oct 9, 2025
bb53e70
partially fix lint issues
rainsxng Oct 9, 2025
1f34d89
remove triling spaces
rainsxng Oct 9, 2025
d7fff24
fix trailing spaces
rainsxng Oct 9, 2025
4c189b5
update the unusual characters
rainsxng Oct 9, 2025
df84e7a
fix PR comments
rainsxng Oct 10, 2025
c417446
fixing xrefs
rainsxng Oct 10, 2025
160ceab
Apply suggestions from code review
IEvangelist Oct 13, 2025
c62472b
remove extra usage section
rainsxng Oct 15, 2025
7ce05d7
Merge remote-tracking branch 'origin/dbohdanov/latency-tags' into dbo…
rainsxng Oct 15, 2025
161dccf
fix conflicts
rainsxng Oct 15, 2025
0076ec3
add explanation text to the measures and tags
rainsxng Oct 15, 2025
e8b4746
fix trailing spaces
rainsxng Oct 15, 2025
40c9291
update measures and tags text
rainsxng Oct 16, 2025
3759be0
fix lint
rainsxng Oct 16, 2025
0cf33df
add text color, fix comments
rainsxng Oct 16, 2025
ad8ba09
remove html tag and fix link
rainsxng Oct 16, 2025
66dd162
using code snippets for samples
rainsxng Oct 17, 2025
835cf70
breaking preview page
rainsxng Oct 17, 2025
e8165eb
add more code snippets
rainsxng Oct 17, 2025
b11b73a
using ranges for the snipets
rainsxng Oct 17, 2025
16ec6f3
add remaining snippets
rainsxng Oct 17, 2025
4f3f23b
use range for snippets
rainsxng Oct 17, 2025
f49a9f6
update snippets lint
rainsxng Oct 17, 2025
c93471a
trying highlight option
rainsxng Oct 17, 2025
27afb15
update highlights
rainsxng Oct 17, 2025
dea281e
fix highlight
rainsxng Oct 17, 2025
e545421
fix relative highlight lines
rainsxng Oct 17, 2025
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
251 changes: 251 additions & 0 deletions docs/core/extensions/httpclient-latency-extensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
---
title: Monitor and analyze HTTP client performance
description: Learn how to use the HttpClientLatency with dependency injection in your .NET workloads.
author: IEvangelist
ms.author: dapine
ms.date: 09/29/2025
---

# HTTP client latency telemetry in .NET

### Get started

When building applications that communicate over HTTP it is important to observe request performance characteristics.
The <xref:Microsoft.Extensions.DependencyInjection.HttpClientLatencyTelemetryExtensions.AddHttpClientLatencyTelemetry*>
extension enables collection of detailed timing information for outgoing HTTP calls with no changes to calling code.
It plugs into the existing `HttpClientFactory` pipeline to capture stage timings across the request lifecycle, record
HTTP protocol details, measure garbage collection impact where the runtime exposes that data, and emit a uniform
telemetry shape suitable for performance analysis and tuning.

### [.NET CLI](#tab/dotnet-cli)

```dotnetcli
dotnet add package Microsoft.Extensions.Http.Diagnostics --version 10.0.0
```

### [PackageReference](#tab/package-reference)

```xml
<PackageReference Include="Microsoft.Extensions.Http.Diagnostics" Version="10.0.0" />
```

---

For more information, see [dotnet package add](../tools/dotnet-package-add.md) or [Manage package dependencies in .NET applications](../tools/dependencies.md).

### Register HTTP client latency telemetry

To add HTTP client latency telemetry to your application, call the <xref:Microsoft.Extensions.DependencyInjection.HttpClientLatencyTelemetryExtensions.AddHttpClientLatencyTelemetry*> extension method when configuring your services:

```csharp
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

// Add HTTP client factory
builder.Services.AddHttpClient();

// Add HTTP client latency telemetry
builder.Services.AddHttpClientLatencyTelemetry();
```

This registration adds a `DelegatingHandler` to all HTTP clients created through <xref:System.Net.Http.IHttpClientFactory>, collecting detailed latency information for each request.

### Configure telemetry options

You configure telemetry collection through the `HttpClientLatencyTelemetryOptions` (standard options pattern).
You can supply values either with a delegate or by binding configuration (e.g. appsettings.json).
The options instance is resolved once per handler pipeline so changes apply to new clients/handlers.

```csharp
// Configure with delegate
builder.Services.AddHttpClientLatencyTelemetry(options =>
{
options.EnableDetailedLatencyBreakdown = true;
});

// Or configure from configuration
builder.Services.AddHttpClientLatencyTelemetry(
builder.Configuration.GetSection("HttpClientTelemetry"));
```

### Configuration options

The <xref:Microsoft.Extensions.Http.Latency.HttpClientLatencyTelemetryOptions*> class offers the following settings:

| Option | Type | Default | Description | When to disable |
|--------------------------------|------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|
| EnableDetailedLatencyBreakdown | bool | true | Enables fine‑grained phase timing for each HttpClient request (e.g. connection establishment, headers sent, first byte, completion) to produce a breakdown of total latency. Adds a small extra CPU/time measurement cost, no wire overhead. | Set to false only in very high‑throughput scenarios where minimal overhead is required and total duration alone is sufficient. |

### Collected telemetry data

When HTTP client latency telemetry is enabled it captures phase timestamps, selected measures (where supported), and protocol attributes used for performance analysis.

#### Timing checkpoints

Timestamps are recorded for key stages of the HTTP request lifecycle:

| Phase | Start Event | End Event | Notes |
|-------------------------|----------------------------|----------------------------|---------------------------------------------------------|
| DNS resolution | Http.NameResolutionStart | Http.NameResolutionEnd | Host name lookup (may be cached and skipped). |
| Socket connection | Http.SocketConnectStart | Http.SocketConnectEnd | CP (and TLS handshake if combined by handler). |
| Connection establishment| | Http.ConnectionEstablished | Marks usable connection after handshake. |
| Request headers | Http.RequestHeadersStart | Http.RequestHeadersEnd | Writing request headers to the wire/buffer. |
| Request content | Http.RequestContentStart | Http.RequestContentEnd | Streaming or buffering request body. |
| Response headers | Http.ResponseHeadersStart | Http.ResponseHeadersEnd | First byte to completion of header parsing. |
| Response content | Http.ResponseContentStart | Http.ResponseContentEnd | Reading full response body (to completion or disposal). |

#### Measures (platform dependent)

| Name | Description |
|--------------------------|-------------------------------------------------------------------------|
| Http.GCPauseTime | Total GC pause duration overlapping the request. |
| Http.ConnectionInitiated | Emitted when a new underlying connection (not pooled reuse) is created. |

#### Tags

| Tag | Description |
|--------------|---------------------------------------------------------|
| Http.Version | HTTP protocol version negotiated/used (e.g. 1.1, 2, 3). |

## Usage Example

### HTTP Client Logs Enrichment and Redaction

These components enable enriching and redacting `HttpClient` request logs. They remove built-it HTTP Client logging.

When using this package, some of the log properties are redacted by default (like full routes), which means that you will need to make sure that a redactor provider is registered in the Dependency Injection container. You can do this by making sure that you call `builder.Services.AddRedaction()` which requires a reference to the `Microsoft.Extensions.Compliance.Redaction` package.

```csharp
public static IServiceCollection AddExtendedHttpClientLogging(this IServiceCollection services)
public static IServiceCollection AddExtendedHttpClientLogging(this IServiceCollection services, IConfigurationSection section)
public static IServiceCollection AddExtendedHttpClientLogging(this IServiceCollection services, Action<LoggingOptions> configure)
public static IServiceCollection AddHttpClientLogEnricher<T>(this IServiceCollection services) where T : class, IHttpClientLogEnricher
```

For example:

```csharp
var builder = Host.CreateApplicationBuilder(args);

// Register IHttpClientFactory:
builder.Services.AddHttpClient();

// Register redaction services:
builder.Services.AddRedaction();

// Register HttpClient logging enrichment & redaction services:
builder.Services.AddExtendedHttpClientLogging();

// Register a logging enricher (the type should implement IHttpClientLogEnricher):
builder.Services.AddHttpClientLogEnricher<MyHttpClientLogEnricher>();

var host = builder.Build();
```

It is important to note that the `AddExtendedHttpClientLogging` method will add information to the logs using *enrichment*. This means that the information will be added as tags to the structured logs, but will not be visible in the log message that is printed by default in the console. To view the information, you will need to use a logging provider that supports structured logs. One quick and built-in way to do this, is to call `AddJsonConsole()` to your logging builder, which will print out the full structured logs to the console. Here is a quick sample that uses the `ExtendedHttpClientLogging()` method to automatically log all `HttpClient` request and response bodies, and then prints the full structured logs to the console:

```csharp
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

var services = new ServiceCollection();

services.AddLogging(o => o.SetMinimumLevel(LogLevel.Trace).AddJsonConsole()); // <-- Enable structured logging to the console

// Adding default redactor provider to the DI container. This is required when using the AddExtendedHttpClientLogging() method.
services.AddRedaction();

services.AddHttpClient("foo")
.AddExtendedHttpClientLogging(o =>
{
// Enable logging of request and response bodies:
o.LogBody = true;

// We also need to specify the content types that we want to log:
o.ResponseBodyContentTypes.Add("application/json");
});

var sp = services.BuildServiceProvider();

var client = sp.GetRequiredService<IHttpClientFactory>().CreateClient("foo");

var response = await client.GetAsync(new Uri("https://httpbin.org/json")).ConfigureAwait(false);
```

By default, request and response routes are redacted for privacy reasons. You can change this behavior by making use of the `RequestPathParameterRedactionMode` option like:

```csharp
.AddExtendedHttpClientLogging(o =>
{
//.. Other options

o.RequestPathParameterRedactionMode = HttpRouteParameterRedactionMode.None; // <-- Disable redaction of request/response routes
});
```

You can also use the following extension methods to apply the logging to the specific `IHttpClientBuilder`:

```csharp
public static IHttpClientBuilder AddExtendedHttpClientLogging(this IHttpClientBuilder builder)
public static IHttpClientBuilder AddExtendedHttpClientLogging(this IHttpClientBuilder builder, IConfigurationSection section)
public static IHttpClientBuilder AddExtendedHttpClientLogging(this IHttpClientBuilder builder, Action<LoggingOptions> configure)
```

For example:

```csharp
var builder = Host.CreateApplicationBuilder(args);

// Register redaction services:
builder.Services.AddRedaction();

// Register named HttpClient:
var httpClientBuilder = builder.Services.AddHttpClient("MyNamedClient");

// Configure named HttpClient to use logging enrichment & redaction:
httpClientBuilder.AddExtendedHttpClientLogging();

var host = builder.Build();
```

### Tracking HTTP Request Client Latency

These components enable tracking and reporting the latency of HTTP Client request processing.

The services can be registered using the following methods:

```csharp
public static IServiceCollection AddHttpClientLatencyTelemetry(this IServiceCollection services)
public static IServiceCollection AddHttpClientLatencyTelemetry(this IServiceCollection services, IConfigurationSection section)
public static IServiceCollection AddHttpClientLatencyTelemetry(this IServiceCollection services, Action<HttpClientLatencyTelemetryOptions> configure)
```

For example:

```csharp
var builder = Host.CreateApplicationBuilder(args);

// Register IHttpClientFactory:
builder.Services.AddHttpClient();

// Register redaction services:
builder.Services.AddRedaction();

// Register latency context services:
builder.Services.AddLatencyContext();

// Register HttpClient logging enrichment & redaction services:
builder.Services.AddExtendedHttpClientLogging();

// Register HttpClient latency telemetry services:
builder.Services.AddHttpClientLatencyTelemetry();

var host = builder.Build();
```

### Platform considerations

HTTP client latency telemetry runs on all supported targets (.NET 9, .NET 8, .NET Standard 2.0, and .NET Framework 4.6.2).
Core timing checkpoints are always collected. The GC pause metric (Http.GCPauseTime) is emitted only when running on .NET 8 or .NET 9.
The implementation detects platform capabilities at runtime and enables what is supported without additional configuration.
3 changes: 3 additions & 0 deletions docs/fundamentals/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,9 @@ items:
- name: HTTP client factory
href: ../core/extensions/httpclient-factory.md
displayName: networking,httpclient,http,dependency injection,client,factory,named client,named httpclient,typed client,typed httpclient
- name: Monitor and analyze HTTP client performance
href: ../core/extensions/httpclient-latency-extensions.md
displayName: httpclient,http,client,factory,dependency injection,keyed,keyed di,keyed services
- name: HTTP client factory troubleshooting
href: ../core/extensions/httpclient-factory-troubleshooting.md
displayName: httpclient,http,client,factory,named client,named httpclient,typed client,typed httpclient
Expand Down
Loading