---
title: "HttpClient improvements in .NET 10"
description: "New dotnet version means new features and improvements. There is a nice update to the `HttpClient` class in .NET 10."
updated: 2025-04-28
tags: [".NET 10", "HttpClient", ".NET"]
canonical: "https://steven-giesel.com/blogPost/58680a06-7870-4a36-8a8a-bf1bf5cf30f1/httpclient-improvements-in-net-10"
---

# HttpClient improvements in .NET 10

New dotnet version means new features and improvements. There is a nice update to the `HttpClient` class in .NET 10.

## Content buffering

To understand the improvement, we have to distinguish between two types:
 * We know upfront how much data we will receive (so the `Content-Length` header is set).
 * We don't know how much data we will receive (so the `Content-Length` header is not set).

The improvement is for the latter case. When streaming a response, it can happen that the buffer has to be resized multiple times. This can be expensive, especially if the response is large. The new `HttpClient` implementation in .NET 10 uses a pooled approach to reduce the overhead or creating new buffers. 

Here are some of the improvements (details see: https://github.com/dotnet/runtime/pull/109642):

```no-class
| Method            | Toolchain | Length     | Mean             | Ratio | Allocated     | Alloc Ratio |
|------------------|-----------|------------|------------------|-------|----------------|--------------|
| GetByteArrayAsync| main      | 10000      | 1,114.6 ns       | 1.00  | 10.81 KB       | 1.00         |
| GetByteArrayAsync| pr        | 10000      | 994.3 ns         | 0.89  | 10.84 KB       | 1.00         |
| GetAsync         | main      | 10000      | 1,284.7 ns       | 1.00  | 28.93 KB       | 1.00         |
| GetAsync         | pr        | 10000      | 1,018.1 ns       | 0.79  | 10.84 KB       | 0.37         |
| GetByteArrayAsync| main      | 100000     | 28,454.2 ns      | 1.00  | 98.73 KB       | 1.00         |
| GetByteArrayAsync| pr        | 100000     | 28,038.7 ns      | 0.99  | 98.76 KB       | 1.00         |
| GetAsync         | main      | 100000     | 31,313.5 ns      | 1.00  | 251.58 KB      | 1.00         |
| GetAsync         | pr        | 100000     | 28,186.0 ns      | 0.90  | 98.76 KB       | 0.39         |
| GetByteArrayAsync| main      | 1000000    | 127,633.7 ns     | 1.00  | 978.16 KB      | 1.00         |
| GetByteArrayAsync| pr        | 1000000    | 110,941.5 ns     | 0.87  | 978.11 KB      | 1.00         |
| GetAsync         | main      | 1000000    | 151,716.7 ns     | 1.00  | 2032.28 KB     | 1.00         |
| GetAsync         | pr        | 1000000    | 110,231.7 ns     | 0.73  | 978.1 KB       | 0.48         |
| GetByteArrayAsync| main      | 10000000   | 1,946,940.2 ns   | 1.00  | 9768.06 KB     | 1.00         |
| GetByteArrayAsync| pr        | 10000000   | 1,113,033.0 ns   | 0.57  | 9769.06 KB     | 1.00         |
| GetAsync         | main      | 10000000   | 2,720,321.2 ns   | 1.04  | 32553.84 KB    | 1.00         |
| GetAsync         | pr        | 10000000   | 1,137,477.7 ns   | 0.43  | 9768.88 KB     | 0.30         |
| GetByteArrayAsync| main      | 100000000  | 21,216,153.0 ns  | 1.00  | 97657.44 KB    | 1.00         |
| GetByteArrayAsync| pr        | 100000000  | 17,026,034.7 ns  | 0.80  | 97657.69 KB    | 1.00         |
| GetAsync         | main      | 100000000  | 25,177,538.4 ns  | 1.00  | 260446.05 KB   | 1.00         |
| GetAsync         | pr        | 100000000  | 16,487,114.6 ns  | 0.66  | 97657.69 KB    | 0.37         |
```