Вы админ, девопс или просто человек, на чьих плечах «падает» сайт, когда всё тормозит. Пользователь говорит: «сайт грузится долго», а вам нужно понять — на каком этапе он тормозит: DNS, сеть, TLS, бэкенд или всё сразу.
Самый простой и при этом очень мощный инструмент для такого экспресс‑диагноза, обычный curl из терминала.
В этой первой главе разберём базу:
что именно мы измеряем;
как настроить удобный вывод таймингов в
curl;чем отличается HTTP и HTTPS в измерениях;
какие подводные камни могут сбить вас с пути.
В следующих главах можно будет углубиться: продвинутая диагностика через curl, интеграция с мониторингом и увязка с логами Nginx/PHP-FPM/БД.
Что именно мы измеряем
Когда человек говорит «сайт грузится медленно», он обычно имеет в виду одно число: пока страница не появится. На самом деле это цепочка из нескольких этапов:
time_namelookup — сколько заняло время DNS‑разрешение домена.
time_connect — время до установления TCP‑соединения.
time_appconnect — время на TLS/SSL‑рукопожатие (актуально для HTTPS).
time_pretransfer — момент, когда всё готово к передаче данных (соединение, TLS и заголовки отправлены).
time_starttransfer — когда пришёл первый байт ответа (по сути, TTFB — Time To First Byte).
time_total — полное время запроса до завершения загрузки.
Зная эти этапы, можно быстро понять, виноват ли:
DNS (долго ищем IP),
сеть (подключение/маршрут),
TLS (рукопожатие),
бэкенд/БД (большая разница между
time_pretransferиtime_starttransfer),тяжёлый ответ (роскошный размер
time_totalпри нормальном TTFB).
Проверяем, установлен ли curl
Во многих дистрибутивах curl уже есть по умолчанию. Проверим:
curl --version
Если видите версию — всё хорошо. Если нет, ставим:
Debian/Ubuntu:
sudo apt update
sudo apt install curl
CentOS/Rocky/Alma (yum/dnf):
sudo yum install curl # или
sudo dnf install curl
Arch/Manjaro:
sudo pacman -S curl
Нам достаточно стандартного curl, который есть в репозиториях.
Базовая команда: измеряем время одним запросом
Начнём с простой идеи: сделать запрос к сайту, не показывая HTML, а вывести только тайминги.
Минимальный пример (HTTP или HTTPS — не важно):
curl -s -o /dev/null -w "time_namelookup: %{time_namelookup}\n \
time_connect: %{time_connect}\n \
time_appconnect: %{time_appconnect}\n \
time_starttransfer: %{time_starttransfer}\n \
time_total: %{time_total}\n" https://example.com/
Разберём по частям:
-s— «тихий» режим, без прогресс‑баров.-o /dev/null— вывод ответа отправляем «в никуда», нам не нужен HTML.-w "…"— format string: говоримcurl, какие переменные времени нам напечатать.https://example.com/— сайт, который меряем.
На выходе вы получите аккуратный список таймингов в секундах, например:
time_namelookup: 0.015
time_connect: 0.043
time_appconnect: 0.121
time_starttransfer: 0.280
time_total: 0.420
С одного взгляда видно:
DNS и соединение быстрые;
TLS не слишком тяжёлый;
от
time_appconnectдоtime_starttransferпрошло ~0.16 с — это сервер думает/ходит в БД;от
time_starttransferдоtime_totalпрошло ещё ~0.14 с — значит, тело ответа не слишком тяжёлое.
Делаем формат удобным: выносим в файл
Печатать длинный -w каждый раз — боль. Гораздо удобнее вынести формат в отдельный файл, например curl-format.txt.
Создадим файл:
cat > curl-format.txt << 'EOF'
DNS lookup: %{time_namelookup}s
TCP connect: %{time_connect}s
TLS handshake: %{time_appconnect}s
TTFB: %{time_starttransfer}s
------------------------------
Total time: %{time_total}s
EOF
Обрати внимание: в конце
EOFбез пробелов, а в середине строки%{time_…}— это специальные плейсхолдерыcurl.
Теперь команда становится сильно короче:
curl -s -o /dev/null -w @curl-format.txt https://example.com/
-w @curl-format.txt говорит curl: «прочитай формат из этого файла».
Такой файл удобно держать прямо в домашней директории или в каком‑нибудь ~/bin/tools/ и переиспользовать при любой диагностике.
HTTP vs HTTPS: где появляется TLS
Для HTTP (порт 80) поле time_appconnect будет равно 0 — TLS нет.
Пример:
curl -s -o /dev/null -w @curl-format.txt http://example.com/
Вы увидите:
DNS lookup: 0.010s
TCP connect: 0.030s
TLS handshake: 0.000s
TTFB: 0.120s
------------------------------
Total time: 0.180s
Для HTTPS (порт 443):
curl -s -o /dev/null -w @curl-format.txt https://example.com/
Теперь TLS handshake станет ненулевым. Это время обычно зависит от:
версии протокола (TLS 1.2/1.3),
размера ключей,
настроек сервера и клиента,
необходимости проверки OCSP/CRL (если включено).
Если TLS handshake внезапно стал в несколько раз выше обычного — это повод проверить настройки TLS, нагрузку на сервер, цепочку сертификатов и т.п.
Подводные камни: где можно ошибиться в выводах
Даже опытные админы иногда попадаются на типичных ловушках. Вот самые популярные:
Кэш DNS и /etc/hosts
Первый запрос к домену может иметь больший time_namelookup, последующие — почти 0, потому что кэширует:
локальная система;
локальный
systemd-resolved/dnsmasq;корпоративный DNS.
Чтобы увидеть «честное» время DNS, можно либо отключить кэш (на тестовой машине), либо тестировать с разных хостов, либо явно указывать DNS через resolv.conf или systemd-resolve. Но в реальной жизни нас чаще интересует как раз закэшированное состояние — оно ближе к тому, как живут пользователи.
Прокси и VPN
Иногда вы меряете не сайт, а «скорость своего VPN/прокси» и делаете неверные выводы.
Примеры подводных камней:
на рабочем ноутбуке включён корпоративный прокси;
подключен VPN до другой страны;
на роутере настроен прозрачный прокси.
В таких случаях time_connect и time_total могут быть заведомо хуже, чем у клиентов, которые ходят к сайту напрямую. Лучше всего тестировать с той же геолокации и без лишних посредников, либо осознанно мерить именно через них.
Редиректы и опция -L
Если сайт делает редирект (например, с http:// на https:// или с / на /home), то базовый curl покажет тайминги только для первого запроса.
Чтобы идти по редиректам, используем -L:
curl -s -L -o /dev/null -w @curl-format.txt https://example.com/
В этом случае итоговый time_total — это сумма по всей цепочке. Но: детальные тайминги (time_namelookup, time_connect и т.д.) показываются только для последнего запроса. Для серьёзной диагностики редиректов это важно помнить.
CDN и география
Если сайт за CDN, одно и то же доменное имя может вести на разные узлы, в зависимости от геолокации. Вы можете видеть идеальный time_total из Нидерландов и адски высокий — из другой страны.
Поэтому:
всегда фиксируйте, откуда вы меряете (VPS/сервер, страна, датацентр);
сравнивайте результаты с нескольких локаций, если есть подозрения на проблемы CDN.
В следующих главах можно будет рассмотреть приёмы вроде --resolve и --connect-to, чтобы стрелять curl прямо по IP нужного узла или origin‑сервера.
Мини‑итог
В этом вводном материале мы:
разобрали, из чего состоит «время загрузки сайта»;
научились использовать
curl -wдля измерения ключевых таймингов;вынесли формат в отдельный файл, чтобы не печатать портянку каждый раз;
посмотрели разницу между HTTP и HTTPS в плане таймингов;
разобрали классические подводные камни (DNS‑кэш, VPN, редиректы, CDN).
На практике этого уже достаточно, чтобы:
быстро подтвердить/опровергнуть слова клиента «у вас всё тормозит»;
отличить сетевую проблему от проблемы бэкенда;
за 30 секунд собрать черновой отчёт по производительности.
В следующей глваве мы рассмотрим небольшие скрипты для многократных замеров, посчитаем среднее, p95, сравним IPv4/IPv6, добавим работу с конкретными бэкендами за балансировщиком и начнём двигаться в сторону нормального нагрузочного тестирования. А пока можете сохранить свой curl-format.txt и уже сегодня использовать его как маленький «стетоскоп» для ваших сайтов из терминала.