A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More

Oleksandr Zvieriev
Sep 9, 2024
  3291
(3 votes)

SNAT - Azure App Service socket exhaustion

Did you know that using HttpClient within a using statement can cause SNAT (Source Network Address Translation) port exhaustion? This can lead to serious performance issues in your application.

What happens when SNAT ports are exhausted?

  • Slow or hanging connections to remote endpoints
  • Socket exceptions due to connection timeouts

This issue is hard to replicate in a local environment, but it can severely impact production systems, causing widespread disruptions.

Why is this important?

If your application interacts with multiple third-party APIs, a misconfigured HttpClient can slow down or cause timeouts across all your HTTP requests, even those that are unrelated.

I've seen many different ways to use HttpClient in a wrong way. Few examples:

public async Task<HttpResponseMessage> Get(string? requestUri)
{
    return await new HttpClient().GetAsync(requestUri);
}

In C#, the using statement is typically used to ensure that disposable objects, like HttpClient, are properly disposed of once the block is exited.

However, in the case of HttpClient, it’s best to avoid this pattern. While HttpClient does implement the IDisposable interface, it is designed to be a shared object, meaning that it should not be frequently disposed of and recreated.

public async Task<HttpResponseMessage> Get(string? requestUri)
{
    using (var httpClient = new HttpClient())
        return await httpClient.GetAsync(requestUri);
}
[ServiceConfiguration(typeof(IMyService), Lifecycle = ServiceInstanceScope.Scoped)]
public class MyService : IMyService
{
    private readonly HttpClient _httpClient = new HttpClient();

    public async Task<HttpResponseMessage> Get(string? requestUri)
    {
        return await _httpClient.GetAsync(requestUri);
    }
}

Instead of creating a new instance of HttpClient for each execution you should share a single instance of HttpClient for the entire lifetime of the application.

Here i'll show a better way to do so:

[ServiceConfiguration(typeof(IMyService), Lifecycle = ServiceInstanceScope.Singleton)] will help you to have a singleton for IMyService instance

[ServiceConfiguration(typeof(IMyService), Lifecycle = ServiceInstanceScope.Singleton)]
public class MyService : IMyService
{
    private readonly HttpClient _httpClient = new HttpClient();

    public async Task<HttpResponseMessage> Get(string? requestUri)
    {
        return await _httpClient.GetAsync(requestUri);
    }
}

In .NET Core, it's recommended to create a reusable client using an injected IHttpClientFactory object.

Now i'll show the best way to use IHttpClientFactory with services:

// register specific client in StartUp.cs
services.AddHttpClient("MyClient", (provider, client) => {
    client.BaseAddress = new Uri("YOU URL");
    client.DefaultRequestHeaders.Add("x-api-key", "YOUR API KEY");
 });
[ServiceConfiguration(typeof(IMyService), Lifecycle = ServiceInstanceScope.Singleton)]
public class MyService : IMyService
{
    private readonly IHttpClientFactory _httpClientFactory;

    public OrderHistorySyncService(IHttpClientFactory httpClientFactory)
    {
       _httpClientFactory = httpClientFactory;
    }

    public async Task<HttpResponseMessage> Get(string? requestUri)
    {
        return await _httpClientFactory.CreateClient("MyClient").GetAsync(requestUri);
    }
}
Sep 09, 2024

Comments

Vladimir
Vladimir Sep 12, 2024 03:40 PM

Good job Olek, that explains a lot!

Please login to comment.
Latest blogs
Troubleshooting with Azure Application Insights Using KQL

Users at least get access to Azure Application Insights even within minimum access level if you are requesting access to DXP management portals at...

K Khan | Dec 21, 2025

Looking back at Optimizely in 2025

Explore Optimizely's architectural shift in 2025, which removed coordination cost through a unified execution loop. Learn how agentic Opal AI and...

Andy Blyth | Dec 17, 2025 |

Cleaning Up Content Graph Webhooks in PaaS CMS: Scheduled Job

The Problem Bit of a niche issue, but we are building a headless solution where the presentation layer is hosted on Netlify, when in a regular...

Minesh Shah (Netcel) | Dec 17, 2025

A day in the life of an Optimizely OMVP - OptiGraphExtensions v2.0: Enhanced Search Control with Language Support and Synonym Slots

Supercharge your Optimizely Graph search experience with powerful new features for multilingual sites and fine-grained search tuning. As search...

Graham Carr | Dec 16, 2025