diff --git a/OptimizelySDK/OptimizelySDK.csproj b/OptimizelySDK/OptimizelySDK.csproj
index 1812a2ad..585d0b0a 100644
--- a/OptimizelySDK/OptimizelySDK.csproj
+++ b/OptimizelySDK/OptimizelySDK.csproj
@@ -173,6 +173,7 @@
+
diff --git a/OptimizelySDK/Utils/HttpClientProvider.cs b/OptimizelySDK/Utils/HttpClientProvider.cs
new file mode 100644
index 00000000..7507d76b
--- /dev/null
+++ b/OptimizelySDK/Utils/HttpClientProvider.cs
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2023 Optimizely
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Net.Http;
+using System.Threading.Tasks;
+
+namespace OptimizelySDK.Utils
+{
+ ///
+ /// Provides a singleton instance of HttpClient to prevent socket exhaustion.
+ ///
+ public class HttpClientProvider
+ {
+ private static readonly object lockObject = new object();
+ private Lazy _httpClient = new Lazy(CreateNewHttpClient);
+
+ ///
+ /// Gets a thread-safe, singleton instance of HttpClient.
+ ///
+ /// HttpClient instance
+ public HttpClient GetClient()
+ {
+ if (IsDisposed(_httpClient.Value))
+ {
+ lock (lockObject)
+ {
+ if (IsDisposed(_httpClient.Value))
+ {
+ _httpClient = new Lazy(CreateNewHttpClient);
+ }
+ }
+ }
+
+ return _httpClient.Value;
+ }
+
+ ///
+ /// Creates a new HttpClient instance.
+ ///
+ /// HttpClient instance
+ private static HttpClient CreateNewHttpClient()
+ {
+ return new HttpClient();
+ }
+
+ ///
+ /// Checks if the HttpClient is disposed by attempting to access a property that
+ /// will throw an exception if the client is disposed.
+ ///
+ /// Client to check
+ /// True if the client is disposed, false otherwise.
+ private static bool IsDisposed(HttpClient httpClient)
+ {
+ try
+ {
+ _ = httpClient.BaseAddress;
+ }
+ catch (ObjectDisposedException)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+}