CLI AI

Как измерить время ответа API с помощью curl

2026-06-22

Самый быстрый способ узнать, сколько времени занял запрос к API — curl -s -o /dev/null -w '%{time_total}\n' https://api.example.com/, он печатает только итоговое время и ничего больше. Одно число не скажет, в чём задержка: в DNS, в сети, в TLS или в самом сервере — для этого запрос нужно разложить на этапы. Дальше — пять чисел вместо одного и что делать с каждым.

1. Одно число

clai
$ clai сколько секунд отвечает этот адрес→ curl -s -o /dev/null -w '%{time_total}\n' https://cliai.tech/1.244094

-o /dev/null выбрасывает тело ответа, -s убирает индикатор прогресса, -w печатает только запрошенное. Число есть, но оно ничего не объясняет.

2. Разложить на этапы

clai
$ clai разложи время ответа по этапам: dns, соединение, tls, первый байт→ curl -s -o /dev/null -w 'dns: %{time_namelookup}\nconnect: %{time_connect}\ntls: %{time_appconnect}\nttfb: %{time_starttransfer}\ntotal: %{time_total}\n' https://cliai.tech/dns: 0.000782connect: 0.299098tls: 0.414729ttfb: 1.124750total: 1.244094

Значения нарастающие, а не независимые. Интересны разности: DNS занял 0,0008, установка TCP-соединения — 0,298, рукопожатие TLS — 0,116, а вот от готовности TLS до первого байта прошло 0,71 секунды — это время работы сервера. Здесь и находится проблема, если она есть.

3. Читать разности, а не абсолютные значения

time_namelookup больше 0,1 с — проблема с резолвером или холодный кеш. Разность connect - namelookup — это сетевая задержка до сервера, она примерно равна половине пинга. Разность starttransfer - appconnect — это то, сколько сервер думал. Разность total - starttransfer — время передачи тела, оно зависит от размера ответа.

4. Это вообще был 200-й?

clai
$ clai покажи время, код ответа и размер тела→ curl -s -o /dev/null -w 'code: %{http_code}  size: %{size_download}  total: %{time_total}\n' https://cliai.tech/code: 200

Без кода ответа замер бесполезен: быстрая 500-я не означает, что всё хорошо. Полный список переменных — в man curl, раздел WRITE-OUT.

5. Замерить несколько раз

clai
$ clai замерь время ответа пять раз подряд→ for i in $(seq 5); do curl -s -o /dev/null -w '%{time_total}\n' https://cliai.tech/; done

Одно измерение ничего не значит. Первый запрос почти всегда медленнее из-за холодного DNS и установки соединения. Смотрите на разброс, а не на первое число.

6. Вынести формат в файл

clai
$ clai сохрани формат замера в файл и используй его→ curl -s -o /dev/null -w @curl-format.txt https://cliai.tech/

-w @файл читает формат из файла, и длинная строка перестаёт мешать. Такой файл кладут в репозиторий рядом со скриптами проверки.

Грабли

  • Значения нарастающие. time_appconnect включает в себя и DNS, и соединение. Вычитайте предыдущий этап, иначе решите, что TLS занимает полсекунды, хотя это сумма всего до него.
  • time_appconnect равен нулю для http. Без TLS этого этапа просто нет, и ноль здесь не ошибка измерения.
  • curl измеряет один запрос, а не производительность. Для нагрузки нужны hey, wrk или k6. curl отвечает на вопрос «где именно теряется время», а не «сколько выдержит сервер».

Похожие вопросы

Что такое TTFB? Время до первого байта ответа. В выводе это time_starttransfer. Обычно именно оно отражает скорость работы бэкенда.

Почему первый запрос медленнее? Холодный DNS-кеш, установка TCP-соединения и рукопожатие TLS. Повторный запрос по keep-alive их пропускает.

Как замерить только DNS? %{time_namelookup} в одиночку, либо dig +stats — он покажет время запроса отдельно от всего остального.

Читайте также

Не запоминайте форматы -w в curl — опишите, что хотите измерить, а команду напишет CliAI. Установка одной строкой.