Before any bytes of your HTTP request exist, two negotiations already happened. Both cost round trips, and round trips are the latency budget.
SYN, SYN-ACK, ACK. One round trip before the connection is usable, spent agreeing on sequence numbers and window sizes. Nothing application-level travels here.
TLS 1.2 needs two round trips: ClientHello with supported ciphers, ServerHello with the certificate, then key exchange and Finished. TLS 1.3 folds a key share into the first message and completes in one, with resumption able to send data immediately.
A cold HTTPS request pays DNS, TCP and TLS before the first byte of the request. Keep-alive amortizes all of it. In .NET this is exactly why a new HttpClient per call is a bug — it burns sockets and repeats every handshake. A pooled HttpClient reuses the connection.
// registers a pooled, rotating handler
builder.Services.AddHttpClient<RatesClient>(c =>
{
c.BaseAddress = new Uri("https://rates.internal/");
c.Timeout = TimeSpan.FromSeconds(5);
});dig +short api.example.com
curl -w "dns %{time_namelookup} connect %{time_connect} tls %{time_appconnect} ttfb %{time_starttransfer}\n" -o /dev/null -s https://api.example.com/healthThose five numbers separate a slow network from a slow application. If ttfb minus tls is large, the problem is your code — not the wire.