Use curl's time_namelookup, time_connect, time_appconnect, time_starttransfer, and time_total to locate a slow web request. They are cumulative timestamps from the beginning of the transfer. Subtract adjacent milestones before assigning time to DNS, TCP, TLS, server work, or download.

A high TTFB does not automatically mean an application is slow. An uncached name lookup, a distant TCP endpoint, TLS negotiation, an edge proxy, and the origin can all contribute before the first response byte arrives. curl's write-out fields give an inexpensive first pass. Their limits matter: redirects, connection reuse, proxies, and HTTP/2 change what an individual number can tell you.
Capture a repeatable timing row
Start with one URL and no redirects. The curl manual defines every field below. Output goes to /dev/null, but curl still downloads the body, so the total includes transfer time. Save the version, source machine, destination IP, HTTP code, and redirect count with every incident capture.
cat > /tmp/curl-timing.txt <<'EOF'
dns=%{time_namelookup} tcp=%{time_connect} tls=%{time_appconnect} pre=%{time_pretransfer} first=%{time_starttransfer} total=%{time_total} code=%{http_code} redirects=%{num_redirects} ip=%{remote_ip}
EOF
curl -sS -o /dev/null --max-time 20 -w @/tmp/curl-timing.txt https://enterno.io/
Make separate IPv4 and IPv6 runs when only some users report slowness. A normal dig lookup establishes which records exist; curl then measures the path actually selected by its connection logic. For a suspected TLS fault, inspect SNI and trust using the OpenSSL command set.

Read milestones as cumulative time
The libcurl API describes these as elapsed time since the start. connect - namelookup approximates the TCP phase; appconnect - connect approximates the TLS phase; starttransfer - pretransfer covers waiting for the first response byte after curl is ready to transfer. total - starttransfer covers the rest of the response. These differences are useful for a fresh, direct HTTPS connection. They are not per-component tracing through every proxy.
| Milestone | Question it helps answer | Next check |
|---|---|---|
time_namelookup | Was name resolution slow? | Compare resolvers and cached answers. |
time_connect | Did opening the TCP path take time? | Inspect address family and network route. |
time_appconnect | Was TLS negotiation delayed? | Check handshake, SNI and certificate chain. |
time_starttransfer | When did the first byte arrive? | Compare with edge and origin logs. |
time_total | When was the response complete? | Look at response size and throughput. |
Do not subtract time_connect from time_total and call the remainder “server time”. The remainder still includes TLS and body transfer. A server-side span or a shared request ID across proxy and application logs is needed to isolate processing. Ping can expose basic reachability but does not measure this HTTP request.
A three-site capture from one vantage point
We ran curl 8.12.1 three times per URL on 13 November 2026 from one server. Each of the three chosen URLs returned HTTP 200 without redirects. The table gives medians in milliseconds, rounded to one decimal place. These are cumulative milestones, not a ranking of providers: one source location, different response bodies, IPv4 versus IPv6 routing, and transient caches make a broad performance comparison invalid.
| URL | DNS | TCP | TLS | First byte | Total |
|---|---|---|---|---|---|
| enterno.io | 0.8 | 37.8 | 87.8 | 141.7 | 288.0 |
| www.cloudflare.com | 0.7 | 4.5 | 14.7 | 25.9 | 57.7 |
| yandex.com | 0.7 | 41.2 | 85.9 | 204.2 | 358.3 |
The first enterno.io run reached its first byte at 0.144038 seconds and finished at 0.273420 seconds. The roughly 129 ms remainder is a transfer interval, not evidence that a PHP handler needed that long. We also ran a separate yandex.ru request with -L; it followed two redirects, which is why it is excluded from the direct-request table. The DNS propagation guide explains one source of inconsistent name answers across locations.
Turn the slow phase into a diagnostic route
If name lookup dominates, compare the authoritative answer with recursive resolvers and inspect record TTL. If TCP dominates, separate -4 and -6, inspect the selected remote IP, and check packet loss at the network edge. A long TLS phase calls for a handshake probe and certificate check; do not turn verification off with -k just to make a run appear fast. If the gap after pretransfer grows, use proxy and application logs with the same request ID. A large interval after the first byte points toward body size, compression, streaming, or client throughput.
curl -4 -sS -o /dev/null -w @/tmp/curl-timing.txt https://example.com/
curl -6 -sS -o /dev/null -w @/tmp/curl-timing.txt https://example.com/
curl -sS -o /dev/null -w 'redirects=%{num_redirects} redirect_time=%{time_redirect} total=%{time_total}\n' -L https://example.com/
Collect several runs under the same conditions and retain the raw output. A single warm request can hide the DNS and handshake costs seen by a new visitor, while a one-off cold request may exaggerate them.
How we made this
The capture used curl 8.12.1 with OpenSSL 3.5.8 on srv2029141.hstgr.cloud on 13 November 2026. The draft archive contains argv, exit code, status, remote IP, redirects and timing fields for each attempt. The three table URLs had no redirects; a fourth, yandex.ru, was used only to demonstrate the effect of -L. Times are site and route snapshots, not service guarantees. We compared official curl documentation with the fields returned by the installed binary.
Frequently asked questions
Is time_starttransfer application processing time?
No. It includes name resolution, connection establishment, TLS, request transfer, proxies and processing before the first response byte.
Why can time_appconnect be zero?
A fresh TLS negotiation may not occur on a reused connection. Inspect connection reuse and run conditions before treating zero as a measurement error.
Should I always use -L?
Use it to measure all redirects to the final page. Measure without it first when you need one server response, then account for time_redirect on the full path.
Can curl diagnose a slow DNS provider by itself?
It gives a symptom from one host. Compare direct authoritative and recursive DNS queries, repeat from other locations, and check caching before assigning cause.