Skip to content
RU
← All articles

curl Timing Breakdown: DNS, TCP, TLS, TTFB and Total Time

In short:

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.

Network engineer workstation with timing instruments and network hardware
A curl capture separates network setup from first-byte wait.

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.

Sequence of network nodes traversed by a web request
curl milestones are cumulative; subtract them to estimate phase durations.

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.

MilestoneQuestion it helps answerNext check
time_namelookupWas name resolution slow?Compare resolvers and cached answers.
time_connectDid opening the TCP path take time?Inspect address family and network route.
time_appconnectWas TLS negotiation delayed?Check handshake, SNI and certificate chain.
time_starttransferWhen did the first byte arrive?Compare with edge and origin logs.
time_totalWhen 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.

URLDNSTCPTLSFirst byteTotal
enterno.io0.837.887.8141.7288.0
www.cloudflare.com0.74.514.725.957.7
yandex.com0.741.285.9204.2358.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.

Sources

Check your website right now

Check your site's HTTP status →
More articles: HTTP
HTTP
How to Fix 404 Not Found Errors: Visitors, nginx, Apache, CDN
15.04.2026 · 2 585 views
HTTP
HTTP Methods Explained: GET, POST, PUT, DELETE and Beyond
16.03.2026 · 1 499 views
HTTP
Server-Sent Events vs WebSockets: Which to Use for Realtime
16.03.2026 · 1 293 views
HTTP
HTTP Request Lifecycle: DNS, TCP, TLS, Request, Response
16.03.2026 · 1 225 views