Зачем вообще разбираться в iowait и steal time
На VDS задержки почти всегда выглядят одинаково: растёт load average, пользователи жалуются на «подвисания», а в логах приложений появляются timeout, upstream timed out или просто скачет время ответа. Проблема в том, что load average не говорит почему очередь растёт: процессы могут ждать диск (iowait), ждать CPU из-за конкуренции на стороне гипервизора (steal), или зависать в непрерываемом ожидании (D-state) из‑за проблем I/O и блокировок.
Ниже — рабочая схема диагностики latency на Linux-VDS тремя базовыми утилитами из пакетов sysstat/procps: vmstat, iostat, pidstat. Цель — за 10–15 минут ответить на вопросы:
- это медленное хранилище или «украденный CPU» (steal);
- очередь на диск растёт из‑за одного процесса или из‑за общей нагрузки;
- что именно тормозит: чтение, запись,
fsync, метаданные, swap, journal.
Быстрый чек-лист: какие симптомы к чему относятся
Упрощённо можно думать так:
- Высокий iowait — CPU простаивает, потому что процессы ждут завершения I/O. Частые причины: очередь диска, синхронные записи, фоновая запись, интенсивные записи БД, swap.
- Высокий steal time — процессам нужен CPU, но гипервизор «крадёт» время: конкуренция с другими ВМ или ограничения по CPU.
- Высокий load average — растёт число задач в runnable (
R) и/или в непрерываемом ожидании I/O (D). Поэтому load может расти и при iowait, и при steal, и при CPU-bound.
Высокий
%wa— это не «CPU перегружен», а «CPU простаивает, потому что I/O не успевает». Высокий%st— сигнал про конкуренцию за CPU на стороне виртуализации.
Подготовка: что поставить и как снимать метрики корректно
На Debian/Ubuntu обычно достаточно:
apt update
apt install -y sysstat
На RHEL/Alma/Rocky:
dnf install -y sysstat
Метрики лучше снимать серией измерений 30–120 секунд, а не «одним кадром». Почти все команды ниже используйте в режиме «интервал + несколько выборок».
Шаг 1. Понимаем, что именно растит load average
Начинаем с простого — текущая нагрузка и число CPU:
uptime
nproc
Дальше — vmstat. Это самый быстрый способ увидеть баланс CPU (user/system/iowait/steal) и общую картину по runnable/blocked задачам.
vmstat 1 30
На что смотреть в выводе:
r— сколько задач готовы к выполнению (run queue). Еслиrстабильно больше числа vCPU, CPU не успевает выполнять желающих.b— задачи в непрерываемом ожидании (обычно I/O). Еслиbрастёт вместе с load — часто это диск или файловая система.si/so— swap in/out. Если они не нули под нагрузкой — latency может быть следствием нехватки RAM.us/sy— пользовательское/системное CPU.wa— iowait.st— steal time.
Как интерпретировать типовые сценарии по vmstat
Сценарий A: высокий wa, растёт b, CPU us невысокий. Почти наверняка упираетесь в диск/хранилище или в синхронные записи. Переходим к iostat и pidstat -d.
Сценарий B: высокий st, при этом wa небольшой. Это конкуренция на стороне гипервизора. Приложение «хочет CPU», но не получает. Дальше имеет смысл смотреть pidstat -u, а также проверить квоты/лимиты CPU (особенно если внутри контейнеров).
Сценарий C: высокий us и/или sy, r большой, wa и st низкие. Классическая CPU-bound нагрузка или много системных вызовов (криптография, сжатие, сетевой стек, частые контекст‑переключения). Здесь уже помогают профилировщики, но в рамках статьи важно зафиксировать, что это не диск и не steal.
Если вы регулярно упираетесь в CPU/RAM и хотите заранее подобрать конфигурацию под тип нагрузки, полезно держать под рукой заметку про выбор тарифа: как прикинуть нужные vCPU и память для VDS.

Шаг 2. Диск и очередь: iostat и disk queue depth
Когда подозрение падает на I/O, цель — понять, какой именно девайс тормозит и есть ли очередь запросов (disk queue depth). Запускаем расширенный iostat по всем устройствам:
iostat -x 1 30
Ключевые поля (могут слегка отличаться по версии sysstat):
%util— насколько устройство занято. 100% не всегда «плохо», но если при этом растут задержки — устройство не справляется.r/s,w/s,rkB/s,wkB/s— интенсивность чтения/записи.await— среднее время ожидания операции (включает время в очереди + сервисное время).avgqu-sz— средний размер очереди (практический аналог «queue depth» в диагностике).aqu-sz— близкий показатель очереди в новых версиях sysstat.
Практическая интерпретация очереди
Если avgqu-sz (или aqu-sz) стабильно больше 1 на одном устройстве и одновременно await растёт до десятков/сотен миллисекунд — запросы стоят в очереди. Это и даёт iowait, D-state и «дерганую» latency.
Условные ориентиры (не абсолют):
- SSD/NVMe:
awaitобычно однозначные миллисекунды. Стабильные 20–50+ мс под умеренной нагрузкой часто означают проблему (лимиты, перегруз, фоновые операции, storage contention). - HDD или «как HDD» на VDS: задержки выше; на распределённом/сетевом хранилище «hdd‑поведение» нередко указывает на перегруз storage или соседей по хранилищу.
Высокий iowait может быть даже при невысоком
%util, если задержки приходят «из сети» (распределённое хранилище) или запросы блокируются на уровне ФС/барьеров. Смотрите связку: очередь +await+ характер нагрузки.
Чтение или запись: почему это важно
Дальше уточняем, что именно давит:
- Запись: WAL/binlog, частые
fsync, интенсивное логирование, commit на каждый запрос, мелкие синхронные записи. - Чтение: cache-miss после рестарта, холодный кэш, сканы таблиц/индексов, чтение больших файлов без кэширования.
- Метаданные: много операций create/unlink/stat (tmp‑файлы, распаковки, сборки, composer/npm).
Если нужно копнуть глубже именно в I/O профиль (планировщик, прямые тесты, iotop/fio), пригодится отдельный материал: как связать iostat/iotop/fio и понять, что делает диск.
Шаг 3. Находим виновника: pidstat (по CPU и по диску)
Даже если диск «плохой», почти всегда есть процесс, который создаёт очередь. Для этого pidstat часто удобнее, чем пытаться глазами читать top.
Кто грузит CPU и есть ли steal на фоне
Смотрим потребителей CPU с интервалом:
pidstat -u 1 30
Если общий симптом — «мало CPU», а vmstat показывает высокий st, вы увидите процессы, которые хотят CPU, но система «не успевает» без явного iowait. Это типичная картина для steal time.
Кто создаёт I/O очередь
Смотрим I/O по процессам:
pidstat -d 1 30
Поля зависят от версии, но обычно это kB_rd/s, kB_wr/s, иногда iodelay. Практика простая:
- если один процесс стабильно пишет/читает больше остальных — начните с него;
- если объём записи небольшой, но всё «залипает» — подозревайте мелкие синхронные операции (
fsync), которые объёмом маленькие, но по латентности дорогие.
Блокировки и D-state: быстрый допчек
Когда load высокий, а CPU визуально «пустой», полезно быстро проверить, не забиты ли процессы в D-state:
ps -eo pid,stat,comm,wchan:40 --sort=stat | head -n 30
Если видите много процессов со статусом D и похожими wchan — это подтверждает I/O‑путь (диск, ФС, storage).
Как отличить iowait от steal time на практике (и не ошибиться)
Самая частая ошибка — делать вывод по одному показателю. Работает только связка инструментов.
Признаки, что это iowait/диск
vmstat: растутwaиb.iostat -x: растутawaitи очередь (avgqu-sz/aqu-sz) на конкретном устройстве.pidstat -d: видно процесс(ы), активно читающие/пишущие.
Признаки, что это steal time/конкуренция за CPU
vmstat: заметныйst(часто двузначные проценты) при умеренномwa.iostat: нет выраженного роста очередей/await, диски выглядят «нормально».pidstat -u: процессы хотят CPU, но система в целом как будто «недодаёт» вычисления.
Почему load average вводит в заблуждение
load average часто воспринимают как «проценты CPU», но это не так. Load — это среднее число задач, которые готовы выполняться (R) или находятся в непрерываемом ожидании (D), обычно из‑за I/O.
Поэтому на VDS возможна ситуация: load = 30 на 4 vCPU, CPU «как будто» 10–20%, и всё тормозит. Это классика для дисковой очереди: задачи копятся в D-state, CPU простаивает, пока I/O не завершится. А может быть и наоборот: load высокий из‑за runnable задач, но CPU‑время «крадётся» как steal.
Мини-ранбук: diagnose latency за 5 команд
Если нужно действовать быстро (инцидент, пользователи ждут), используйте такой порядок:
uptimeиnproc— понять масштаб относительно CPU.vmstat 1 20— увидетьwa/st,r,b, swap.iostat -x 1 20— найти устройство с ростомawaitи очереди.pidstat -d 1 20— найти процесс, создающий I/O.pidstat -u 1 20— если подозрение на steal/CPU, найти, кто упирается в CPU.

Что делать после диагностики (без «магии», только типовые действия)
Если упёрлись в диск и очередь растёт
- Уберите лишние синхронные записи: проверьте настройки БД/журналирования, частоту flush/checkpoint, уровень логирования.
- Разнесите роли: БД и веб/воркеры на разные инстансы или разные диски, чтобы очередь не мешала.
- Проверьте swap: если есть активный
si/so, сначала добавьте RAM или уменьшите потребление памяти. - Оцените профиль I/O: много мелких writes обычно хуже для latency, чем крупные последовательные операции.
Если высокий steal time
- Снизьте пики CPU: ограничьте параллелизм воркеров/очередей/фоновых задач.
- Проверьте, не упираетесь ли в квоты/лимиты CPU (особенно в контейнерах).
- Если нагрузка постоянная и
stстабильно высокий — пересмотрите класс/тариф и требования к изоляции ресурсов.
Частые ловушки и неверные выводы
«iowait низкий — значит диск ни при чём»
Не всегда. Если основной затык — в приложении (например, блокировки в БД) или I/O «размазан» и не приводит к долгому ожиданию на стороне CPU, %wa может быть умеренным. Смотрите await и очередь в iostat, а также D-state через ps.
«%util 100% — срочно апгрейдить диск»
100% занятости может быть нормой при устойчивой throughput-нагрузке, если await низкий и очередь не растёт. Плохо, когда %util высокий и растут await + avgqu-sz/aqu-sz.
«load average высокий — добавим CPU»
Если load растёт из‑за D-state (I/O), добавление vCPU часто не помогает. Сначала подтвердите через vmstat (b, wa) и iostat (очередь/await), что это действительно CPU-дефицит, а не storage latency.
Итог
Чтобы диагностировать задержки на VDS, не гадайте по одному графику. Соберите связку: vmstat (баланс CPU, iowait, steal time, runnable/blocked), iostat -x (очередь, await, %util) и pidstat (кто именно грузит CPU или диск). В большинстве случаев этого достаточно, чтобы локализовать узкое место и выбрать корректное действие: оптимизировать I/O профиль, убрать лишние sync-записи, исправить дефицит памяти/свап или признать проблему конкуренции за CPU (steal) на уровне виртуализации.
Если вы выбираете площадку под предсказуемую производительность, логично держать запас по ресурсам и изоляции. При необходимости можно посмотреть тарифы VDS и подобрать конфигурацию под ваш профиль нагрузки.


