Выберите продукт

CPU throttling на VDS в Linux: TDP/thermal лимиты, частоты и квоты cgroups v2 (cpu.max)

Если на VDS растёт load average и задержки, а CPU «не на 100%», причина часто в throttling: тепловые/мощностные лимиты, steal time гипервизора или квоты cgroups v2. Разберём быстрый чек-лист и аккуратное управление CPU через systemd.
CPU throttling на VDS в Linux: TDP/thermal лимиты, частоты и квоты cgroups v2 (cpu.max)

Просадки производительности на VDS часто выглядят одинаково: нагрузка есть, load average растёт, а запросы внезапно выполняются в 2–5 раз дольше. При этом на графиках CPU может не быть 100% — либо ядра «залипают» на пониженной частоте. Это типичный сценарий throttling: процессор ограничивает частоту или планировщик ограничивает время исполнения из-за лимитов мощности (TDP/PL), температуры, энергополитик или квот CPU в cgroups.

Ниже — практический разбор, как отличать причины, какие подсистемы Linux участвуют (intel_pstate, cpufreq, turbo), где смотреть лимиты мощности (powercap/RAPL), как быстро измерять (turbostat, perf), и как контролировать квоты в cgroups v2 через cpu.max и systemd slices.

Что именно называется throttling: три разных механизма

Важно разделить «тормоза CPU» на классы. Симптомы похожи, но действия по исправлению — разные.

1) Thermal throttling (температурный)

CPU снижает частоту/напряжение, когда упирается в температурный лимит. На физическом сервере это часто связано с охлаждением и обдувом. На VDS вентиляторами вы не управляете, но последствия видите в гостевой ОС: частота падает, задержки растут.

2) TDP-limit / power limit (ограничение по мощности)

Современные Intel/AMD ограничивают потребление через power limits (у Intel обычно PL1/PL2). Даже при нормальной температуре процессор может резать частоту, чтобы уложиться в заданный лимит мощности. В реальности это один из самых частых «неожиданных» сценариев: под длительной нагрузкой частота стабилизируется ниже ожидаемой.

3) Квоты/шаринг на уровне виртуализации и cgroups

  • CPU steal time: гипервизор отнимает время у вашей VM, потому что физические ядра заняты другими гостями. Внутри Linux это видно как steal в top/vmstat.
  • Лимиты cgroups: вы сами (или панель/оркестратор) ограничили сервисам CPU через cgroups v2. Тогда процессы «душатся» по расписанию: им не дадут больше N микросекунд CPU на период (см. cpu.max).

Быстрый чек‑лист: чем вызваны просадки на VDS

Когда есть инцидент и нужно понять «кто виноват» за 5–10 минут, начните с минимального набора проверок.

Шаг 1. Проверить steal time

top -b -n 1 | head -n 15

В строке CPU в top смотрите st. Если st заметно ненулевой (условно 5–20% и выше на длительном интервале), это сильный кандидат на проблемы уровня гипервизора/переподписки CPU: вы просто ждёте, пока VM дадут исполняться.

vmstat 1 10

В колонке st будет steal.

Шаг 2. Проверить текущие частоты и драйвер (intel_pstate / cpufreq)

uname -r
lscpu | egrep -i 'model name|mhz|cpu\(s\)|thread|core|socket'
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver 2>/dev/null || echo no-cpufreq

Если видите intel_pstate — это обычный современный вариант для Intel. Если acpi-cpufreq — управление частотой идёт через классический cpufreq-драйвер. Если файла нет, возможно, в VM частоты «спрятаны» гипервизором, и детальную телеметрию вы не увидите.

Шаг 3. Посмотреть governor и ограничения

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 2>/dev/null
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq 2>/dev/null
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq 2>/dev/null

Если scaling_max_freq неожиданно низкий — возможно, выставлен лимит частоты политикой ядра или окружением (включая настройки хоста).

Вывод top/vmstat и чтение параметров cpufreq для первичной диагностики просадок CPU

Шаг 4. Снять turbostat: есть ли признаки ограничений

turbostat — один из лучших инструментов для диагностики turbo, idle‑состояний и ограничений. На Debian/Ubuntu обычно ставится из пакета linux-tools (название пакета зависит от ядра).

turbostat --Summary --interval 1 --num_iterations 10

Что смотреть в выводе:

  • падает ли Bzy_MHz под нагрузкой и «не поднимается»;
  • есть ли признаки ограничений по мощности/температуре (зависит от модели CPU и доступности MSR);
  • не слишком ли много времени CPU проводит в idle при «вроде бы» высокой нагрузке (тогда проблема может быть не в CPU, а в I/O/локах).

Если turbostat в VM ничего полезного не показывает или ругается на недоступные MSR/PMU — это ограничение виртуализации. Тогда опирайтесь на косвенные признаки: стабильная низкая частота, отсутствие роста при нагрузке и рост времени выполнения задач при неизменном коде.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Как работает intel_pstate, cpufreq и turbo (и где легко ошибиться)

Частая ошибка: думать, что governor performance автоматически держит максимум частоты всегда. На современных Intel с intel_pstate реальная частота — это компромисс между запросом нагрузки, лимитами мощности/температуры и энергополитикой.

intel_pstate: active/passive и EPP

У intel_pstate есть два основных режима:

  • active: драйвер сам управляет P‑states, а классические governors ведут себя не так, как вы ожидаете по старым гайдам;
  • passive: управление через стандартный cpufreq-интерфейс и governors.

На некоторых системах доступна настройка EPP (Energy Performance Preference) — она может «держать» частоты ниже, чем ожидается, даже если в целом выбран производительный профиль. Проверка (если интерфейс доступен):

cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference 2>/dev/null

Почему «не бустится» turbo

Turbo почти всегда упирается в один из лимитов:

  • температура (thermal throttling);
  • лимиты мощности PL1/PL2 (TDP/power limit);
  • ограничение максимальной частоты политикой;
  • в виртуализации — ограничения хоста или политика провайдера.

Для Intel состояние turbo нередко видно так:

cat /sys/devices/system/cpu/intel_pstate/no_turbo 2>/dev/null

Значение 1 обычно означает «turbo выключен». Но даже при 0 turbo может не проявляться, если срабатывает power limit.

Powercap и TDP-limit: где в Linux живут лимиты мощности

Подсистема powercap в Linux даёт интерфейс к RAPL (Running Average Power Limit) на Intel. На «железе» это позволяет увидеть (а иногда и настроить) лимиты мощности. На VDS доступность зависит от гипервизора: часто RAPL скрывают.

Проверка наличия powercap:

ls -1 /sys/class/powercap 2>/dev/null || echo no-powercap

Если каталог есть, можно исследовать содержимое (названия доменов отличаются):

find /sys/class/powercap -maxdepth 3 -type f -name 'name' -o -name 'enabled' -o -name 'constraint_*_power_limit_uw' 2>/dev/null

Практический смысл:

  • если долгий лимит (аналог PL1) слишком низкий, CPU будет стабильно работать на «неожиданно» низких частотах под длительной нагрузкой;
  • если лимит короткого буста (аналог PL2) низкий, не будет коротких «взлётов» частоты на пиках.

На большинстве VDS вы не сможете менять RAPL/PL1/PL2 из гостя, даже если что-то видно. Но диагностика полезна: вы хотя бы докажете, что упёрлись именно в power limit, а не в «плохой код».

cgroups v2: cpu.max, cpu.weight и почему сервис «душится» при свободном CPU

Если система на unified hierarchy (cgroups v2), ограничения CPU задаются иначе, чем в v1. Главный файл — cpu.max. Он задаёт квоту и период: сколько времени CPU можно потреблять за период. Это «throttling» планировщика, а не железа.

Как проверить, что система на cgroups v2

stat -fc %T /sys/fs/cgroup

Если увидите cgroup2fs — это v2.

Посмотреть лимиты для текущего процесса

Для быстрой диагностики удобно начать с PID проблемного процесса:

PID=1234
cat /proc/$PID/cgroup

Дальше найдите соответствующий каталог в /sys/fs/cgroup и проверьте:

CG=/sys/fs/cgroup/your.slice/your.service
cat $CG/cpu.max
cat $CG/cpu.stat
cat $CG/cpu.weight 2>/dev/null

Как интерпретировать:

  • cpu.max вида max 100000 — квоты нет (безлимит), период 100 ms.
  • cpu.max вида 20000 100000 — квота 20 ms на 100 ms, то есть 20% одного CPU.
  • cpu.stat содержит счётчики throttling (часто поля nr_throttled, throttled_usec). Их рост под нагрузкой — прямое подтверждение cgroup‑throttling.

systemd slices: где чаще всего «прячут» лимиты

На системах с systemd ограничения часто задаются декларативно через unit‑файлы и slices. Типовые сценарии:

  • панель/оркестратор ограничил группу сервисов в отдельном slice;
  • вы ограничили фоновые задачи через CPUQuota= и забыли, а в пике получили задержки;
  • в контейнерной среде лимит выставлен контейнеру, а приложение думает, что у него все ядра.

Проверить ограничения systemd для конкретного сервиса:

systemctl show your.service -p CPUQuota -p CPUQuotaPeriodSec -p Slice -p AllowedCPUs

А для slice целиком:

systemctl show your.slice -p CPUQuota -p CPUQuotaPeriodSec -p AllowedCPUs

Если хотите глубже разобраться в лимитах systemd (CPU/Memory/Tasks), полезно держать под рукой материал: лимиты systemd для CPU и памяти.

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

perf: как отличить «CPU медленнее» от «CPU не дают»

perf полезен в двух ситуациях: (1) вы подозреваете, что частоты упали (TDP/thermal), (2) вы подозреваете cgroup/steal и хотите увидеть, что процесс больше ждёт, чем считает.

Быстрый профиль без flamegraph

perf stat -p 1234 -- sleep 10

Смотрите на:

  • task-clock и долю времени в CPU;
  • context-switches и cpu-migrations (могут резко расти при перегрузе/квотах/лишних воркерах);
  • инструкции/циклы (если доступны): на VDS PMU может быть недоступен, это нормально.

Системный взгляд на нагрузку

perf top

Если в топе в основном планировщик/синхронизация, а не «полезная работа» приложения, то проблема часто не в «медленном CPU», а в contention, ожиданиях, блокировках или ограничении по квоте.

Типовые причины просадок на VDS и что с ними делать

Сценарий A: частота не растёт, ограничения по мощности/температуре

  • Признаки: steal низкий; задержки растут; частота по наблюдениям низкая и почти не меняется под нагрузкой; на железе turbostat/датчики показывают ограничения.
  • Действия: на своём железе проверьте охлаждение и powercap; на VDS фиксируйте факт (время, нагрузка, вывод turbostat при возможности) и эскалируйте провайдеру; со стороны приложения снижайте пики (ограничение параллелизма, очереди, backpressure), чтобы не загонять CPU в длительный power‑limit режим.

Сценарий B: высокий steal time

  • Признаки: заметный st в top/vmstat; при том же QPS задержки «плавают»; частота может быть нормальной.
  • Действия: соберите историю st во время инцидента и сопоставьте с latency; изнутри VM это не лечится; часто помогает переход на более предсказуемый класс виртуализации или увеличение vCPU.

Сценарий C: cgroups v2 cpu.max ограничивает сервис

  • Признаки: steal низкий; в cpu.stat растёт throttling; общесистемно CPU «свободен», но сервис не выходит за определённый процент.
  • Действия: найдите место, где задан лимит (unit systemd, slice, контейнерный runtime); разделите сервисы по slices (интерактивный веб без жёсткой квоты, фон с квотой и меньшим весом через cpu.weight); проверьте соответствие квоты модели параллелизма (например, 20% одного CPU при 8 воркерах даст лишние переключения контекста).

Схема slices systemd и дерева cgroups v2 с квотами CPU через cpu.max

Практика: аккуратное управление CPU лимитами через systemd (cgroups v2)

Подход для типичного VDS с вебом и фоновой обработкой: вебу — низкая задержка, фону — предсказуемое потребление, чтобы не устраивать конкуренцию в пике.

Создаём отдельный slice для фоновых задач

Сделайте drop‑in для slice:

mkdir -p /etc/systemd/system/background.slice.d
cat > /etc/systemd/system/background.slice.d/10-cpu.conf << 'EOF'
[Slice]
CPUQuota=50%
CPUWeight=100
EOF
systemctl daemon-reload

Применение настроек для slice обычно достаточно сделать через перезапуск сервисов, которые в него входят. Если slice уже используется, можно перезапустить связанные сервисы; сам slice как «юнит» перезапускают не всегда, поэтому ориентируйтесь на факт изменения параметров в cgroup‑файлах.

Назначаем сервису slice

systemctl edit workers.service
[Service]
Slice=background.slice
systemctl daemon-reload
systemctl restart workers.service

Проверка результата:

systemctl show workers.service -p Slice -p CPUQuota
cat /sys/fs/cgroup/background.slice/cpu.max
cat /sys/fs/cgroup/background.slice/cpu.stat

Нюансы в контейнерах: когда cpufreq «ни при чём»

В контейнерах частая ловушка — искать проблему в intel_pstate/cpufreq, когда на самом деле контейнеру выставили квоту CPU. Для cgroups v2 это тот же cpu.max, но в дереве cgroup контейнера. Признак прежний: растёт throttling в cpu.stat, а приложение не масштабируется по воркерам.

Практический совет: заставьте приложение подстраивать число воркеров под фактическую квоту, а не под число «видимых» CPU. Иначе получите лишние переключения контекста и рост latency даже при «свободном» хосте.

Резюме: как не гадать, а доказывать причину throttling

Чтобы уверенно объяснить «почему стало медленно», собирайте доказательства по слоям:

  • Гипервизор/шаринг: steal в top/vmstat.
  • cgroups v2: cpu.max и рост throttling в cpu.stat.
  • Частота/boost: данные turbostat (если доступны) и cpufreq‑интерфейсы (scaling_driver, scaling_max_freq, no_turbo).
  • Профиль нагрузки: perf stat/perf top чтобы отделить «CPU медленнее» от «CPU не дают» и от проблем синхронизации.

Если по итогам видно, что вы упёрлись в хост‑уровень (power/thermal/steal) и нужна предсказуемая производительность, имеет смысл выбирать тарифы и ресурсы под пиковую нагрузку: например, перейти на VDS с подходящим числом vCPU и стабильными лимитами.

А если «тормоза» оказались на уровне диска, а не CPU, полезно свериться с практикой измерений и тюнинга I/O: диагностика дисковой подсистемы (iostat/iotop/fio).

Поделиться статьей

Вам будет интересно

Let’s Encrypt через DNS-01: wildcard, автоматизация продления и безопасные deploy-хуки OpenAI Статья написана AI (GPT 5)

Let’s Encrypt через DNS-01: wildcard, автоматизация продления и безопасные deploy-хуки

DNS-01 удобен для wildcard и закрытых сетей: владение доменом подтверждается TXT-записью в DNS. Разбираем выбор certbot/lego/acme. ...
MySQL replication lag на VDS: диагностика и лечение (GTID, relay log, parallel replication) OpenAI Статья написана AI (GPT 5)

MySQL replication lag на VDS: диагностика и лечение (GTID, relay log, parallel replication)

Replication lag в MySQL — не всегда «медленный slave»: показатель Seconds_Behind_Master часто врёт. Покажу, как отличить проблему ...
Linux: EIO и Buffer I/O error on dev — диагностика диска, ФС и контроллера OpenAI Статья написана AI (GPT 5)

Linux: EIO и Buffer I/O error on dev — диагностика диска, ФС и контроллера

EIO, I/O error и Buffer I/O error on dev обычно означают сбой чтения/записи: диск, контроллер, кабели, RAID или файловая система. ...