正确写法是 curl -s -o /dev/null -w "dns:%{time_namelookup}, connect:%{time_connect}, appconn:%{time_appconnect}, prexfer:%{time_pretransfer}, startxfer:%{time_starttransfer}\n" url,需注意dns缓存干扰、https握手测量及限流规避。

curl -w 输出各阶段耗时的正确参数写法
直接用 curl -w 查响应时间,最常踩的坑是没加 -o /dev/null 或 -s,导致响应体混在输出里,-w 的时间字段根本没法解析。必须把响应内容屏蔽掉,只让格式化的时间数据出来。
curl -s -o /dev/null -w "DNS: %{time_namelookup}, TCP: %{time_connect}, TTFB: %{time_starttransfer}, Total: %{time_total}\n" https://example.com-
%{time_namelookup}是 DNS 解析完成到发起 TCP 连接前的耗时,单位秒(含小数),不是“纯 DNS 查询时间”,它包含本地 hosts 查找、DNS 缓存命中判断等 -
%{time_connect}是从开始到 TCP 连接建立完成(三次握手结束),不含 TLS 握手;若用 HTTPS,要加%{time_appconnect}才能看完整握手耗时 - 所有时间变量只在请求成功时有值;遇到 DNS 失败或连接拒绝,整个
-w输出可能为空或不完整,需配合-f判断是否失败
区分 HTTP 和 HTTPS 的 TLS 握手时间测量
HTTPS 站点的延迟瓶颈常卡在 TLS 握手,但默认 %{time_connect} 不包含它。必须显式启用 %{time_appconnect},且注意它的触发条件。
- 仅当 URL 是
https://且 curl 编译时启用了 OpenSSL / GnuTLS / mbedTLS 才有效;用curl -V看输出里有没有SSL字样 - 若服务端支持 TLS 1.3,
%{time_appconnect}可能接近 0,因为 1.3 握手和首字节传输合并了,此时要看%{time_pretransfer}更准 - 推荐组合:
curl -s -o /dev/null -w "DNS:%{time_namelookup}, Connect:%{time_connect}, AppConn:%{time_appconnect}, PreXfer:%{time_pretransfer}, StartXfer:%{time_starttransfer}\n" https://example.com
排查 DNS 缓存干扰的真实解析耗时
本地 /etc/hosts、systemd-resolved、浏览器 DNS 缓存都会让 %{time_namelookup} 显示极低(如 0.000015),误判 DNS 快。要测真实公网解析,得绕过所有缓存层。
- 加
--dns-servers 8.8.8.8强制指定 DNS 服务器,跳过系统配置(注意:此参数要求 curl ≥ 7.33.0) - 更彻底的方法是用
dig +short example.com @8.8.8.8单独测 DNS,再对比 curl 中的%{time_namelookup}—— 若后者明显更长,说明 curl 在做额外动作(比如尝试 IPv6 AAAA 记录失败后回退) - 用
-4强制 IPv4 可避免 AAAA 查询拖慢 DNS 阶段,尤其对只部署了 A 记录的老站点
批量测试时避免被目标限流或误判超时
连发多次 curl 测平均值很常见,但默认无延时、无 User-Agent、无 Referer,容易触发 WAF 或 CDN 的速率限制,导致后续请求返回 429 或直接断连。
- 加
--retry 2 --retry-delay 1避免单次网络抖动影响统计;但别设--retry-max-time过小,否则短超时会掩盖真实慢响应 - 用
-H "User-Agent: curl-monitor/1.0"模拟合理客户端,部分 CDN 对空 UA 会降权或限速 - 关键:每次请求后加
sleep 0.5(不要用0.1),既保证采样密度,又避开多数防护策略的阈值(通常按秒级窗口计数)
真正难的是把 %{time_namelookup} 和 %{time_connect} 的微小差异归因到具体环节——比如是本地 stub resolver 转发慢,还是 upstream DNS 响应毛刺,还是中间某段网络丢包重传。这时候得切到 tcpdump 或 strace -e trace=connect,sendto,recvfrom curl ... 才能定位。单纯靠 -w 输出,永远只能看到结果,看不到路径。










