'-w', or '--write-out', prints a template after the transfer with variables filled in, which turns curl into a precise measurement tool without any extra dependency. Useful fields include %{http_code}, %{time_namelookup}, %{time_connect}, %{time_appconnect} for the TLS handshake, %{time_starttransfer} for time to first byte, %{time_total}, %{size_download}, %{num_redirects}, %{url_effective} and %{remote_ip}.
Subtracting the cumulative timers isolates each phase, so a slow %{time_appconnect} minus %{time_connect} points at TLS rather than at the application. Combine with '-o /dev/null -sS' to measure without saving the body.
Two conveniences: the template supports '\n' for a newline, and prefixing a filename with an at-sign reads the format from that file, which keeps a long template out of the shell quoting. Since curl 7.70.0 '%{json}' emits every available variable as a JSON object in one go, which is the easiest thing to pipe into jq for structured logging. Values are per-transfer, so with '-L' they describe the final request unless the redirect-specific variables are used.