diff --git a/src/FSharp.Data.Http/Http.fs b/src/FSharp.Data.Http/Http.fs
index e394ad507..d34cc9514 100644
--- a/src/FSharp.Data.Http/Http.fs
+++ b/src/FSharp.Data.Http/Http.fs
@@ -2043,6 +2043,12 @@ type Http private () =
req.AutomaticDecompression <- DecompressionMethods.GZip ||| DecompressionMethods.Deflate
+ // Optimize HTTP performance with connection keep-alive and pooling
+ req.KeepAlive <- true
+ req.ServicePoint.UseNagleAlgorithm <- false // Disable Nagle for better latency
+ req.ServicePoint.Expect100Continue <- false // Reduce handshake overhead
+ req.ServicePoint.ConnectionLimit <- 10 // Allow more concurrent connections per endpoint
+
// set cookies
let addCookiesFromHeadersToCookieContainer, cookieContainer =
match cookieContainer with
diff --git a/tests/FSharp.Data.Benchmarks/FSharp.Data.Benchmarks.fsproj b/tests/FSharp.Data.Benchmarks/FSharp.Data.Benchmarks.fsproj
index 57119c667..f1ddf1c93 100644
--- a/tests/FSharp.Data.Benchmarks/FSharp.Data.Benchmarks.fsproj
+++ b/tests/FSharp.Data.Benchmarks/FSharp.Data.Benchmarks.fsproj
@@ -14,6 +14,7 @@
PreserveNewest
+
diff --git a/tests/FSharp.Data.Benchmarks/HttpBenchmarks.fs b/tests/FSharp.Data.Benchmarks/HttpBenchmarks.fs
new file mode 100644
index 000000000..2396da47e
--- /dev/null
+++ b/tests/FSharp.Data.Benchmarks/HttpBenchmarks.fs
@@ -0,0 +1,76 @@
+namespace FSharp.Data.Benchmarks
+
+open System
+open System.Net
+open BenchmarkDotNet.Attributes
+open FSharp.Data
+
+[]
+[]
+type HttpBenchmarks() =
+
+ // Use public HTTP test endpoints for realistic benchmarks
+ let httpBinUrl = "https://httpbin.org"
+ let smallEndpoint = $"{httpBinUrl}/get"
+ let jsonEndpoint = $"{httpBinUrl}/json"
+
+ []
+ member _.SingleHttpBinRequest() =
+ try
+ Http.RequestString(smallEndpoint, timeout = 5000)
+ with
+ | :? WebException -> "Network error" // Handle network issues in CI
+
+ []
+ member _.HttpBinJsonRequest() =
+ try
+ Http.RequestString(jsonEndpoint, timeout = 5000)
+ with
+ | :? WebException -> "Network error" // Handle network issues in CI
+
+ []
+ member _.MultipleSequentialRequests() =
+ for _ in 1..3 do
+ try
+ Http.RequestString(smallEndpoint, timeout = 5000) |> ignore
+ with
+ | :? WebException -> () // Handle network issues in CI
+
+ []
+ member _.PostRequest() =
+ let body = TextRequest "test data"
+ try
+ Http.RequestString($"{httpBinUrl}/post", httpMethod = "POST", body = body, timeout = 5000)
+ with
+ | :? WebException -> "Network error" // Handle network issues in CI
+
+ []
+ member _.RequestWithHeaders() =
+ let headers = [("User-Agent", "FSharp.Data.Benchmarks"); ("Accept", "application/json")]
+ try
+ Http.RequestString(smallEndpoint, headers = headers, timeout = 5000)
+ with
+ | :? WebException -> "Network error" // Handle network issues in CI
+
+ []
+ member _.TypeProviderWorkloadSimulation() =
+ // Simulate a type provider fetching sample data and caching
+ for _ in 1..2 do
+ try
+ Http.RequestString(jsonEndpoint, timeout = 5000) |> ignore
+ with
+ | :? WebException -> () // Handle network issues in CI
+
+ []
+ member _.MultipleConnectionsToSameHost() =
+ // Test connection reuse with keep-alive optimization
+ let endpoints = [
+ $"{httpBinUrl}/get"
+ $"{httpBinUrl}/json"
+ $"{httpBinUrl}/user-agent"
+ ]
+ for endpoint in endpoints do
+ try
+ Http.RequestString(endpoint, timeout = 5000) |> ignore
+ with
+ | :? WebException -> () // Handle network issues in CI
\ No newline at end of file
diff --git a/tests/FSharp.Data.Benchmarks/Program.fs b/tests/FSharp.Data.Benchmarks/Program.fs
index 49be49dc0..e94066026 100644
--- a/tests/FSharp.Data.Benchmarks/Program.fs
+++ b/tests/FSharp.Data.Benchmarks/Program.fs
@@ -10,9 +10,11 @@ let main args =
match args with
| [| "json" |] -> BenchmarkRunner.Run() |> ignore
| [| "conversions" |] -> BenchmarkRunner.Run() |> ignore
+ | [| "http" |] -> BenchmarkRunner.Run() |> ignore
| _ ->
printfn "Running all benchmarks..."
BenchmarkRunner.Run() |> ignore
BenchmarkRunner.Run() |> ignore
+ BenchmarkRunner.Run() |> ignore
0
\ No newline at end of file