LobeLOBE

Learn

How to measure DNS, TCP, and TLS time

Three tools break an HTTP request into its connection phases: curl -w for a single request from the command line, the browser DevTools Timing tab for page traffic, and a local capture proxy for every request your app makes. Each reports the same four setup phases — DNS lookup, TCP connect, TLS handshake, then time to first byte — and knowing which phase is inflated tells you which layer to fix.

Option 1: curl -w (single request, any URL)

curl -w '
dns        %{time_namelookup}s
tcp        %{time_connect}s
tls        %{time_appconnect}s
ttfb       %{time_starttransfer}s
total      %{time_total}s
' -o /dev/null -s https://api.example.com/health

Note the values are cumulative: time_connect includes DNS, time_appconnect includes both, and so on. Subtract neighbors to get per-phase costs (TLS cost = appconnect − connect). Run it twice: the second run often reuses OS DNS cache, showing you how much of the first run was resolution.

Option 2: browser DevTools

Network panel → click a request → Timing tab. Chrome labels the phases DNS Lookup, Initial connection, SSL, Waiting for server response (that’s TTFB), and Content Download. Watch for the phases being absent: on a reused keep-alive or HTTP/2 connection, DNS/connect/SSL show as zero — which is the correct, healthy state for every request after the first.

Option 3: a local capture proxy (every request, continuously)

The one-off tools answer “how slow is this URL right now”; they can’t tell you what your app does across a whole session of real usage. A local profiler like Lobe sits as a reverse proxy in front of your dev server (lobe capture http://localhost:3000), and every request that flows through gets the full DNS/TCP/TLS/TTFB/download decomposition, with each phase judged against a baseline for your environment — so a 400ms TLS handshake gets flagged while a 4ms pooled request doesn’t trip a false alarm.

What each phase should cost — and what it means when it doesn’t

  • DNS: ~0–20ms (cached: 0). Consistently slow → resolver problems, or the localhost/IPv6 fallback trap on local dev.
  • TCP: one round trip — ~0ms loopback, 1–5ms LAN, 20–150ms internet. High TCP with low DNS → distance or packet loss.
  • TLS: roughly 1–2× the TCP time (one to two more round trips). Wildly higher → misconfigured certificates, OCSP stalls, or an overloaded server’s accept queue.
  • Nonzero TCP/TLS on every request: the finding that pays the rent — your client isn’t reusing connections, and you’re paying handshakes that keep-alive would eliminate.

Measure it instead of guessing: Lobe is a free, local HTTP profiler — one command captures every request’s DNS, TCP, TLS, TTFB, and download time, judged against grounded baselines. No agent, no account. brew install kpwithcode/lobe/lobe or cargo install lobe-cli. How it works →