How to Measure Website Response Time and HTTP Status Codes in Linux Using curl -w

When troubleshooting slow web applications, diagnosing latency bottlenecks, or verifying API endpoint health, developers and network administrators often need precise performance metrics. While full graphical browser developer tools provide detailed waterfall graphs, they introduce local rendering overhead and cannot easily be scripted on headless remote servers. The ubiquitous Linux command-line tool curl provides an extraordinarily flexible feature: the -w (or --write-out) option, which extracts microsecond-accurate network timing variables directly from the terminal.

Understanding How curl -w Measures Latency

During an HTTP/HTTPS transfer, your connection progresses through several distinct network phases: DNS resolution, TCP handshake, TLS cryptographic negotiation, server processing time (time to first byte), and content transfer. The -w flag instructs curl to format and print specific telemetry variables after the transfer has completed, without modifying the requested remote payload.

Basic Syntax for Measuring Latency

To measure total transfer time and suppress the actual webpage HTML output, use the silent flag -s, redirect the output to /dev/null, and specify the timing variable:

curl -s -o /dev/null -w "Total Time: %{time_total}s\n" https://example.com

In this command:

  • -s (silent): Suppresses progress bars and standard error output.
  • -o /dev/null: Discards the response body so your terminal is not flooded with HTML or JSON data.
  • -w "Total Time: %{time_total}s\n": Prints the elapsed duration in seconds, down to millisecond precision.

Inspecting HTTP Status Codes and Redirection Details

In addition to latency, you can inspect the response code and final target URL when following redirects:

curl -s -o /dev/null -L -w "HTTP Status: %{http_code} | Final URL: %{url_effective} | Time: %{time_total}s\n" https://example.com

The -L flag instructs curl to follow HTTP 301/302 redirects, while %{http_code} prints the numeric response (such as 200, 301, 404, or 500) and %{url_effective} reports the ultimate landing destination.

Building a Complete Network Timing Waterfall in Terminal

To diagnose where latency is occurring—whether in DNS lookup, SSL handshake, or server response—you can construct a structured multi-variable template:

  1. Create a reusable formatting text file named curl-format.txt in your home or project directory:
    cat << 'EOF' > ~/curl-format.txt
       DNS Lookup Time:   %{time_namelookup}s
       TCP Connect Time: %{time_connect}s
     TLS Handshake Time: %{time_appconnect}s
      Pre-Transfer Time: %{time_pretransfer}s
      Start-Transfer Time: %{time_starttransfer}s
    -------------------------------------------
              Total Time: %{time_total}s
             HTTP Status: %{http_code}
    EOF
  2. Run curl referencing your format file with the @ prefix:
    curl -s -w "@$HOME/curl-format.txt" -o /dev/null https://example.com

Analysing Key curl Timing Variables

Reviewing the output breakdown pinpoints server and networking issues immediately:

  • time_namelookup: The time from the start until DNS name resolution completes. High values indicate sluggish or overloaded DNS resolvers.
  • time_connect: Time until the remote host establishes a TCP connection. High values point to network congestion, geographical distance, or firewall delays.
  • time_appconnect: The time required for SSL/TLS certificate verification and cryptographic key exchange to finish.
  • time_starttransfer: Often termed TTFB (Time to First Byte). This measures the time from connection initiation until the server generates and delivers its very first byte of data. Elevated numbers indicate heavy back-end database queries or unoptimised server code.
  • time_total: Complete end-to-end duration of the entire request and download cycle.

Benchmarking with a Rapid Multi-Request One-Liner

If you want to take five consecutive measurements to check latency stability:

for i in {1..5}; do curl -s -o /dev/null -w "Run $i: Status: %{http_code} | Total: %{time_total}s | TTFB: %{time_starttransfer}s\n" https://example.com; sleep 1; done

This automated loop offers a quick, dependency-free benchmarking tool to audit web services directly from any Linux shell session.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.