PSI (Pressure Stall Information) — механизм ядра Linux, который отвечает на практичный вопрос: не «сколько ресурсов занято», а «сколько времени процессы не могли продолжать полезную работу из‑за дефицита CPU, памяти или I/O».
Если вы ловили ситуацию «CPU вроде не 100%, диски не красные, а задержки в приложении прыгают», PSI помогает быстро подтвердить факт pressure и понять его тип: CPU, memory или I/O.
Дальше — разбор, как читать /proc/pressure, что означают some/full, как использовать avg10/avg60/avg300 и total, и как применять PSI в triage на уровне системы и cgroups.
Что измеряет PSI и почему это не «ещё одна метрика загрузки»
Классические метрики (load average, iowait, %util, free/available) в основном отвечают на вопрос «насколько ресурс занят». PSI отвечает на другой: «сколько времени полезная работа не выполнялась, потому что задача упёрлась в дефицит ресурса».
В терминах ядра pressure — это ситуация, когда задачи вынуждены ждать:
- CPU: runnable-задачи ждут процессорное время (очередь на CPU).
- Memory: задачи блокируются из‑за reclaim/компакции/ожидания освобождения памяти, иногда на фоне свопа.
- I/O: задачи блокируются в ожидании завершения операций чтения/записи.
PSI не «угадывает первопричину». Он фиксирует симптом — stall time — а причину вы находите корреляцией с нагрузкой, лимитами cgroup, поведением диска/свопа и метриками приложения.
Где смотреть: /proc/pressure и формат данных
PSI доступен в трёх файлах:
/proc/pressure/cpu/proc/pressure/memory/proc/pressure/io
Снять текущие значения можно обычным cat:
cat /proc/pressure/cpu
cat /proc/pressure/memory
cat /proc/pressure/io
Типичный вывод:
some avg10=0.25 avg60=0.10 avg300=0.05 total=123456789
full avg10=0.00 avg60=0.00 avg300=0.00 total=0
Что важно:
avg10,avg60,avg300— скользящие средние доли времени (в процентах), когда наблюдался pressure, за 10/60/300 секунд.total— суммарное время давления в микросекундах с момента загрузки (монотонно растёт). Удобно считать дельты.someиfull— два уровня «насколько плохо».
some vs full: как читать уровни давления
some означает: хотя бы одна задача в наблюдаемой области (система целиком или конкретная cgroup) не могла прогрессировать из‑за дефицита данного ресурса.
full означает: все не-idle задачи в наблюдаемой области одновременно не могли прогрессировать из‑за этого ресурса. Это признак «тотальной пробуксовки».
Практически:
someхорошо ловит частичные очереди и микроподвисания, аfull— моменты, когда сервисам реально нечем заняться кроме ожидания (обычно это уже заметно пользователям).
На CPU full часто близок к нулю, а some показывает конкуренцию. Для I/O и memory full встречается чаще при сильной деградации (например, при активном свопе или «затыке» диска).
Если вы отлаживаете PSI на контейнерах или нескольких сервисах, чаще всего упираетесь не в «железо», а в распределение ресурсов и лимиты. На практике проще всего проверять гипотезы на отдельной VDS с предсказуемыми CPU/RAM и понятными лимитами — особенно когда нужно воспроизвести spikes под нагрузкой.

CPU pressure: когда «CPU не 100%», но очередь уже душит
CPU pressure — это время, когда runnable-задачи хотели выполняться, но ждали планировщик. В терминах практики это «цена очереди на CPU», выраженная как доля времени ожидания.
Типичные причины:
- Пиковая нагрузка короткими burst-ами (сжатие, шаблонизация, шифрование, сборка).
- Ограничения CPU в cgroup (контейнеры, systemd slices): по системе в целом CPU может быть не «в красном».
- Слишком мало vCPU для количества воркеров и конкурентных сервисов.
- Перекос по ядрам (IRQ/softirq/NUMA), когда «узкое место» не выглядит как высокий user CPU.
Быстро сопоставить PSI и картину по CPU:
cat /proc/pressure/cpu
uptime
mpstat -P ALL 1 5
Если avg10 по CPU растёт одновременно со скачками latency, а общий %CPU не обязательно упирается в 100% на всех ядрах — проверьте лимиты cgroup и распределение нагрузки по потокам. Для systemd-юнитов полезно держать под рукой разбор лимитов: лимиты CPU и памяти в systemd и cgroups.
Memory pressure: reclaim, swap и «невидимые» паузы
Memory pressure — самая «коварная» часть PSI. Память может быть «вроде есть» (особенно если смотреть только free), но система тратит время на reclaim, ожидание I/O под своп/страницы, компакцию или упирается в лимит cgroup.
Сценарии, где PSI по памяти особенно полезен:
- Короткие latency spikes из‑за периодических волн reclaim/компакции.
- Память ограничена cgroup-лимитом: процесс упирается в лимит и начинает «биться» об reclaim.
- Своп включён и диск не успевает: внешне это похоже на I/O проблему, но корень — в нехватке RAM.
- Непредсказуемые паузы у JVM/Node/PHP-FPM при росте RSS и конкуренции за память.
Минимальный набор команд для триажа рядом с PSI:
cat /proc/pressure/memory
free -m
vmstat 1 5
grep -E 'pgscan|pgsteal|pswp' /proc/vmstat | head
Почему «vmstat vs psi» — не замена, а разные углы
vmstat показывает события и скорости (сканирование страниц, своп, runnable/blocked). PSI показывает влияние на выполнение: сколько времени задачи реально простаивали в ожидании.
Практический подход: vmstat объясняет механизм (reclaim? swap?), а PSI помогает измерить, насколько это бьёт по задержкам и SLO.
I/O pressure: ожидание диска и «неожиданные» очереди
io pressure фиксирует время, когда задачи блокировались на I/O. Это напрямую коррелирует с ситуациями, когда приложение «висит», хотя CPU свободен.
Частые причины:
- Пиковые
fsync/fdatasyncи flush (БД, журналы, интенсивная запись логов). - Промахи по page cache и неудачные паттерны чтения (много случайного чтения, маленькие блоки).
- Конкуренция нескольких сервисов за один диск/том.
- Фоновая активность: бэкапы, ротации, обновления, сканирование.
Быстрый набор для сопоставления:
cat /proc/pressure/io
iostat -xz 1 5
pidstat -d 1 5
Если PSI по I/O растёт одновременно с увеличением await/r_await/w_await или высоким %util в iostat — вы почти наверняка нашли источник latency spikes. Для веб-нагрузки это часто ещё и «обратное давление» на апстримы/воркеры; полезная тема для связки — очереди и backpressure в upstream для nginx.
Если вы наблюдаете стабильный I/O pressure из‑за «шумных соседей» или общий сервер перегружен конкурентными задачами, иногда проще переехать на изолированный виртуальный хостинг под лёгкие проекты или на выделенные ресурсы в VDS для тяжёлых сервисов. PSI как раз помогает аргументировать такой переезд цифрами: «вот сколько времени мы реально стоим и ждём диск/память».

Как ловить spikes: дельты total и простое логирование
Скользящие средние полезны для обзора, но кратковременные пики проще ловить по росту total. Идея: снимать значения раз в секунду и считать дельту между измерениями.
Самый простой «ручной осциллограф» для PSI (вывод в stdout):
while true; do date +%s; awk '{print FILENAME, $0}' /proc/pressure/cpu /proc/pressure/memory /proc/pressure/io; sleep 1; done
Дальше вы либо сохраняете это в лог и сопоставляете со временем инцидента, либо оборачиваете в сборщик метрик. Важно, что вы фиксируете факт: «в такую-то секунду stall time по memory/io/cpu резко вырос».
PSI и cgroups: почему проблема может быть не видна на уровне системы
На контейнерных хостах и серверах с несколькими сервисами по системе в целом PSI может выглядеть терпимо, но один конкретный сервис испытывает сильный pressure внутри своей cgroup.
В cgroup v2 PSI доступен как cpu.pressure, memory.pressure, io.pressure внутри директории cgroup. В systemd дерево обычно живёт в /sys/fs/cgroup по слайсам/юнитам.
Пример: узнать cgroup для сервиса (подставьте имя):
systemctl show -p ControlGroup php-fpm.service
И затем читать PSI прямо там:
cat /sys/fs/cgroup/system.slice/php-fpm.service/cpu.pressure
cat /sys/fs/cgroup/system.slice/php-fpm.service/memory.pressure
cat /sys/fs/cgroup/system.slice/php-fpm.service/io.pressure
Так вы отделяете «системе в целом нормально» от «конкретному сервису плохо» — это особенно полезно, когда SLA завязан на одном приложении.
systemd-oomd и PSI: как OOM становится предсказуемее
systemd-oomd может завершать процессы/юниты заранее, ориентируясь на pressure по памяти (и/или swap), чтобы избежать сценария «ядро внезапно убило самый дорогой процесс». Ключевой момент: он смотрит не только на «сколько памяти осталось», а на симптом — memory pressure.
Практический смысл:
- Если у вас бывают OOM или «подвисания» при нехватке RAM, PSI помогает увидеть нарастание pressure до аварии.
- Можно разделить сервисы по слайсам и задать политику так, чтобы при кризисе «падало менее важное».
systemd-oomdне заменяет тюнинг памяти. Если система постоянно живёт в memory pressure, вы получите либо регулярные убийства, либо деградацию. PSI полезен, чтобы доказать проблему цифрами и выбрать направление: добавить RAM, изменить лимиты, пересмотреть swap, оптимизировать потребление памяти или I/O.
Пороговые значения: что считать «плохо»
У PSI нет универсальных «красных линий» — всё зависит от нагрузки и требований по задержкам. Но удобно мыслить так:
avg10— «прямо сейчас», хорошо ловит всплески.avg60— устойчивая проблема на масштабе минуты.avg300— хроническое давление.
Для latency-чувствительных веб-сервисов даже единицы процентов по memory/io pressure могут отражаться в p95/p99. Для batch/ETL это часто нормально. Правильный путь — коррелировать PSI с метриками приложения (latency, очереди, ошибки) и закрепить пороги под ваш SLO.
Типовые паттерны: как по PSI отличить вероятную первопричину
1) Растёт io pressure, потом растёт memory pressure
Часто означает, что page cache не успевает: диск медленный или перегружен, reclaim становится болезненным. В приложении это выглядит как ступенчатые задержки: то нормально, то «всё стало вязким».
2) Растёт memory pressure, затем io pressure
Часто это активный своп: сначала системе не хватает RAM, затем начинается интенсивный swap in/out, и диску становится плохо тоже. В этот момент особенно полезно смотреть vmstat (si/so) и iostat.
3) Растёт cpu pressure без роста io/memory pressure
Это конкурентная CPU-нагрузка или лимиты CPU. Для подтверждения обычно хватает mpstat, pidstat -u и проверки cgroup-лимитов.
4) PSI «в норме», но задержки есть
PSI измеряет stalls только по CPU/memory/io. Если задержки из‑за сети, блокировок в приложении (lock contention), пауз GC, DNS, или внешних зависимостей — PSI может быть чистым. И это тоже результат: вы быстрее снимаете подозрение с базовых ресурсов.
Мини-чеклист: как внедрить PSI в повседневный triage
Соберите «карту нормы»: какие
avg10/60/300бывают в спокойном режиме и под типичной нагрузкой.При инцидентах фиксируйте PSI рядом с метриками приложения (latency, RPS, очереди, ошибки).
Если есть контейнеры/systemd — смотрите PSI в cgroup проблемного сервиса, а не только по системе.
Отдельно контролируйте memory pressure, если включён своп или есть риск OOM.
Для I/O всегда добавляйте корреляцию с
iostat -xzи per-process I/O черезpidstat -d.
Итоги
Linux PSI — практичный способ измерять не «занятость», а реальную цену дефицита ресурсов во времени: stall time. Метрики из /proc/pressure помогают быстро понять, что именно вызывает latency spikes — cpu pressure, memory pressure или io pressure — и не тратить часы на гадания по косвенным признакам.
Если один раз встроить PSI в стандартный triage (хотя бы руками через /proc/pressure и пару утилит), особенно заметно выигрываете на «плавающих» проблемах: коротких подвисаниях, деградации под пиком и ситуациях, где традиционные графики выглядят «почти нормально».


