Why IHttpClientFactory Will Save Your .NET App (and Your TCP Ports!)



This content originally appeared on DEV Community and was authored by Ibrahim Sow

As .NET developers, we’ve all done this:

var client = new HttpClient();

It’s easy, it works… until your app starts failing unexpectedly due to port exhaustion.
In this article, I’ll explain:

  • Why creating multiple HttpClientinstances is dangerous
  • How IHttpClientFactorysolves the problem
  • How to structure your code using Clean Architecture

❌ The Problem with new HttpClient()

Bad practice: creating HttpClient for every request

public async Task<string> GetWeatherAsync()
{
    using var client = new HttpClient();
    var response = await client.GetAsync("https://api.weather.com/forecast");
    return await response.Content.ReadAsStringAsync();
}

Why is this bad?
Each new HttpClient() opens a fresh TCP connection. When used frequently (e.g., in loops or heavy API calls), this leads to port exhaustion, causing your HTTP requests to fail.

The Right Approach:IHttpClientFactory

.NET introduced IHttpClientFactoryto manage reusable and efficient HttpClientinstances.

Step 1: Define a Service Interface (Clean Architecture)

public interface IWeatherService
{
    Task<string> GetForecastAsync();
}

Step 2: Implement the Service

public class WeatherService : IWeatherService
{
    private readonly HttpClient _httpClient;

    public WeatherService(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<string> GetForecastAsync()
    {
        var response = await _httpClient.GetAsync("/forecast");
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsStringAsync();
    }
}

Step 3: Configure HttpClient in Program.cs

builder.Services.AddHttpClient<IWeatherService, WeatherService>(client =>
{
    client.BaseAddress = new Uri("https://api.weather.com");
    client.DefaultRequestHeaders.Add("Accept", "application/json");
});

With IHttpClientFactory, .NET reuses connections under the hood, improves performance, and avoids port exhaustion.

What About You?

  • Have you ever experienced port exhaustion in production?
  • Do you prefer Named Clients or Typed Clients with IHttpClientFactory?
  • Let me know in the comments – I’d love to hear your experience!

About Me
I’m a C#/.NET & Angular fullstack developer, passionate about building robust SaaS applications and clean, testable architectures
Contact me on LinkedIn


This content originally appeared on DEV Community and was authored by Ibrahim Sow