---
title: "Does an HttpClient await the Header and the body?"
description: "If you call `HttpClient.GetAsync` or `HttpClient.PostAsync` and then `await` the result, does the `await` wait only for the headers to be received or does it wait for the body to be received? Let's find out!"
updated: 2024-06-10
tags: ["C#", ".NET"]
canonical: "https://steven-giesel.com/blogPost/e2c3bcba-4f81-42b0-9b25-060da5e819fa/does-an-httpclient-await-the-header-and-the-body"
---

# Does an HttpClient await the Header and the body?

If you call `HttpClient.GetAsync` or `HttpClient.PostAsync` and then `await` the result, does the `await` wait only for the headers to be received, or does it wait for the body to be received? Let's find out!

## Our simple server
We will create a simple server that sends a response with a header and a body. The body will be sent in chunks so we can see when it is received.

```csharp
app.MapGet("/", async context =>
    {
        await context.Response.WriteAsync("1");
        await Task.Delay(500);
        await context.Response.WriteAsync("2");
        await Task.Delay(500);
        await context.Response.WriteAsync("3");
        await context.Response.CompleteAsync();
    });
```

So, the whole request takes at least 1 second to complete. So, let's write a very simple call to that endpoint

## The client
```csharp
using var client = new HttpClient();

// Let's measure the time it takes to get the response
var sw = Stopwatch.StartNew();
await client.GetAsync("https://localhost:5001");
Console.WriteLine($"Response-Time: {sw.ElapsedMilliseconds}ms");
```

If we execute this code, we will see that the response time is around 1 second. So the `await` waits for the whole response to be received:

```no-class
Response-Time: 1088ms
```

Now that we answered the question, let's see how we can actually **not** await the body! We can use the `HttpCompletionOption.ResponseHeadersRead` option:

```csharp
var sw = Stopwatch.StartNew();
await client.GetAsync("https://localhost:5001", HttpCompletionOption.ResponseHeadersRead);
Console.WriteLine($"Response-Time: {sw.ElapsedMilliseconds}ms");
```

So we added the `HttpCompletionOption.ResponseHeadersRead` flag to the `GetAsync` call. Now the response time is much lower:

```no-class
Response-Time: 78ms
```

So the `await` only waits for the headers to be received. The body is still being received in the background. If you want to wait for the body to be received, you can use the `ReadAsStringAsync` method:

```csharp
using var response = await client.GetAsync("https://localhost:5001", HttpCompletionOption.ResponseHeadersRead);
var body = await response.Content.ReadAsStringAsync();
```

Now very important is that we are using `using var response` - the object is maybe still holding on to resources, so we should dispose it as soon as possible. If you omit the `HttpCompletionOption.ResponseHeadersRead` flag, the `response` object will be disposed when the `await` is done, so you don't have to worry about it.

All in all, there is a performance and memory benefit when using `HttpCompletionOption.ResponseHeadersRead`, and you can still read the body if you want to. **But** you have to be careful with the `response` object, as it might still hold on to resources and your code becomes more complex. So this shouldn't be your default choice, but only if you really need it.