Формула CPU/RAM/полосы для медиа-нагрузки (не AI): подписки = камер × (участников − 1), подтверждено точно двумя боевыми замерами (28.07 и 31.07.2026). Коэффициенты полосы на подписку и CPU на ядро — из тех же замеров, с явными допущениями и предупреждением не путать пиковый трафик с устойчивым. Профили — малая команда/совещание/большое собрание/ смешанная нагрузка, включая пример недостижимого профиля и как его спасают лимит плиток и потолок качества публикации (0.0.21). Перекрёстные ссылки из README, hardware-profiles.md, capacity.md.
22 KiB
Профиль нагрузки → рекомендуемое железо (медиа)
Отвечает на вопрос «сколько CPU, RAM и полосы нужно под ожидаемую видео-нагрузку»
для тех, кто разворачивает VidConf у себя. Разговор именно про медиа
(конференции, LiveKit SFU) — сайзинг под AI (транскрибация/суммаризация) описан
отдельно: install.md, hardware-profiles.md,
ADR-004. Базовый пресет инсталлятора
без AI (4 vCPU / 8 ГБ RAM / 40 ГБ диска) рассчитан именно на медиа-нагрузку —
этот документ объясняет, какую конференцию такое железо реально держит и когда
его уже мало.
От синтетического нагрузочного теста capacity.md (SFU на dev-Mac, формула по CPU) этот документ отличается источником цифр: здесь — измерения на боевом сервере с реальными людьми, не эмуляция.
⚠️ Все числа ниже — ориентировочные, при указанных допущениях. Реальная нагрузка зависит от поведения людей: сколько включат камеру, будет ли демонстрация экрана, как долго говорят несколько человек одновременно. Используйте таблицу как отправную точку для выбора железа, не как гарантию.
Точка привязки к реальности
Единственные цифры ниже, которые не расчёт, а прямое измерение на боевом сервере
(4 CPU, 8 ГБ RAM, Ubuntu 24.04, тот же узел, где сейчас работает vidconf.ru):
| Дата | Версия | Участников | Камер | Подписок на видео | Исходящий трафик LiveKit | CPU LiveKit |
|---|---|---|---|---|---|---|
| 28.07.2026 | 0.0.11, до adaptiveStream |
19 | 17 | ~306 | 140–169 Мбит/с устойчиво (пик 240) | 1.62 ядра из 4 |
| 31.07.2026 | 0.0.13, после adaptiveStream+dynacast |
30 | 27 | 783 | 70.6 Мбит/с | 1.83 ядра из 4 |
Второе измерение и есть якорь для формулы ниже — оно снято на конфигурации,
максимально близкой к дефолтной (пагинация сетки участников, adaptiveStream,
dynacast), без ручной настройки под тест.
Почему не пиковые 240 Мбит/с. Пик — кратковременный всплеск, а не режим, в котором сервер работал устойчиво; 1.62 ядра CPU намерены именно под устойчивые 140–169 Мбит/с. Если посчитать коэффициент «Мбит/с на ядро» по пиковому числу, получится оптимистичнее примерно в полтора раза, чем в реальности — расчёт по такому коэффициенту недооценит нужное железо.
Что показывает разница двух строк. Во второй нагрузка выше (участников ×1.6,
подписок ×2.6), а трафик почти вдвое ниже, при том что CPU почти не
изменился. Это эффект adaptiveStream: клиент подписывается на трек, но получает
битрейт под фактический размер плитки на экране, а невидимые (не помещающиеся на
текущую страницу сетки) треки почти не занимают полосы. Всё, что дальше в этом
документе, посчитано для конфигурации с adaptiveStream (релиз ≥0.0.13, в
проекте включён с этой версии по умолчанию) — без него числа нужно умножать в
разы, см. следующий раздел.
Почему нельзя считать «все видят всех»
SFU (LiveKit) пересылает пакеты, а не микширует их. Наивная формула трафика —
N × (N−1) × битрейт (каждый участник получает поток от каждого) — при 80
участниках даёт единицы гигабит в секунду: недостижимо на одном сервере и не
имеет отношения к тому, что видит пользователь на экране.
Реальная модель другая: клиент подписан не на всех, а на видимые плитки, и
получает под каждую подписку битрейт по фактическому размеру плитки — благодаря
пагинации сетки (с релиза 0.0.11) и adaptiveStream/dynacast (с 0.0.13).
Отсюда рабочая формула:
подписок на видео = камер × (участников − 1)
Она подтверждена обоими измерениями выше точно: 17 × 18 = 306, 27 × 29 = 783. Это формула для типичного «видят всех камер» размещения (сетка без ручного скрытия участников) — при включённом лимите плиток (см. ниже) число подписок не растёт дальше лимита, даже если камер больше.
Насколько наивная формула хуже. Гипотетически, если бы все 75 участников
большого собрания (профиль ниже) были источником видео и каждый получал полный
поток от каждого — 75 × 74 × 1.5 Мбит/с (типичный битрейт публикации без
адаптации) — это 9.48 Гбит/с: недостижимо ни на одном разумном сервере.
Модель выше на сопоставимом масштабе (профиль «Большое собрание», 15 камер из
75) даёт около 182 Мбит/с — в 50 с лишним раз меньше. Разница — не оптимизация
в мелочах, а другая по порядку величины задача, и именно поэтому SFU вообще
годится для конференций на десятки участников.
Аудио в этой формуле — единицы процентов трафика: микрофоны обычно включены у 2–5 человек одновременно, замьюченный трек полосу не занимает, DTX/RED включены по умолчанию. Дальше считаем аудио отдельным слагаемым, не путая с видео.
Формула
1. подписок = камер × (участников − 1)
(если включён лимит плиток в настройках инстанса — camер заменить на min(камер, лимит))
2. видео = подписок × битрейт_на_подписку
битрейт_на_подписку зависит от того, помещаются ли все плитки на одну страницу:
- крупная плитка / говорящий в фокусе (мало плиток на экране) → 450 кбит/с
- мелкая плитка сетки, все участники на одной странице → 150 кбит/с
- сетка с пагинацией (участников больше лимита плиток) → 100 кбит/с
(часть подписок физически не на экране — почти не потребляет полосы)
3. аудио = активных_микрофонов × участников × 40 кбит/с
4. исходящая полоса сервера = видео + аудио ← главный параметр, см. ниже
5. ядер CPU (LiveKit) ≈ max(2, ⌈исходящая_полоса_Мбит/с ÷ 90⌉)
+ 1–2 ядра на остальной стек (backend, БД, Redis, coturn, nginx, ОС)
6. RAM ≈ 4 ГБ база (без AI-профилей) — на этом масштабе RAM не была узким
местом ни на одном реальном или синтетическом тесте, планировать по CPU и полосе
Откуда коэффициенты.
- 450 / 150 кбит/с — измерение одного трека клиентом в крупной и мелкой плитке (релиз 0.0.13), округлено вверх от 453 и 147 для запаса.
- 100 кбит/с — обратный расчёт по якорному замеру 31.07.2026:
70.6 Мбит/с ÷ 783 подписки ≈ 90 кбит/с в среднем, округлено вверх. Число ниже,
чем «мелкая плитка» (147), потому что в комнате на 30 участников часть из 783
подписок физически не помещалась на текущую страницу сетки —
adaptiveStreamпочти обнулил их битрейт, а среднее по всем подпискам это отражает. - 90 Мбит/с на ядро — из 28.07.2026: 140–169 Мбит/с устойчиво ÷ 1.62 ядра = 86–104 Мбит/с/ядро, округлено вниз (консервативно, в пользу большего числа ядер).
- Минимум 2 ядра и запас 1–2 ядра на остальной стек — эмпирический пол: на обоих реальных замерах LiveKit не опускался ниже 1.6 ядра независимо от трафика, а весь остальной стек (backend, Postgres, Redis, coturn, nginx) на боевом сервере устойчиво укладывается в разницу между занятым LiveKit и 4 доступными ядрами.
⚠️ Формула по полосе — не единственная граница. Между двумя замерами подписок стало в 2.6 раза больше, трафик упал вдвое, а CPU почти не изменился (1.62 → 1.83 ядра) — то есть процессор тратится в первую очередь на обработку пакетов/подписок, а не на байты. На сценариях с очень большим числом мелких подписок (много участников, лимит плиток не выставлен) реальный CPU может обогнать то, что предсказывает формула по полосе быстрее, чем ожидается — держите эмпирический пол (2 ядра LiveKit минимум под любую активную конференцию) и не полагайтесь только на деление на 90.
Профили нагрузки
Все профили — при adaptiveStream+dynacast (по умолчанию с 0.0.13) и без
AI-профилей (transcribe/llm). Допущения по камерам/микрофонам — решение,
не измерение; подставьте свои, если знаете реальный сценарий.
| Профиль | Сценарий | Камер | Подписок | Полоса (видео+аудио) | CPU (LiveKit) | RAM | Узкое место |
|---|---|---|---|---|---|---|---|
| Малая команда | 10 параллельных созвонов по 5 чел., 60% с камерой, 2 микрофона в каждом | 3×10 | 12×10=120 | ~58 Мбит/с | 2 ядра | 4 ГБ | нет — запас большой |
| Совещание | 1 конференция × 25 чел., 70% с камерой, 4 микрофона | 18 | 432 | ~69 Мбит/с | 2 ядра | 4 ГБ | полоса — близко к нашему якорю (70.6 Мбит/с на 30 чел.) |
| Большое собрание | 1 конференция × 75 чел., 20% с камерой (камер меньше лимита плиток), 5 микрофонов | 15 | 1110 | ~182 Мбит/с | 3 ядра | 4–6 ГБ | полоса и её цена у хостера |
| Смешанная нагрузка | «Малая команда» + «Совещание» одновременно на одном сервере | — | — | ~127 Мбит/с | 2 ядра | 4 ГБ | суммируется линейно |
Малая команда и совещание укладываются в базовый пресет инсталлятора без AI
(4 vCPU / 8 ГБ) с большим запасом — это ровно тот масштаб, что подтверждён
якорным замером (30 чел./27 камер на этом же железе, CPU занят на 46%). Большое
собрание уже требует железа больше базового пресета — 3 ядра под сам
LiveKit плюс 1–2 под остальной стек означают, что 4 vCPU становятся тесными.
Когда профиль недостижим — и как его спасти
«Большое собрание, все 75 человек с камерой» без ограничений: подписок 75 × 74 = 5550, полоса по коэффициенту пагинации (100 кбит/с) — уже ~555 Мбит/с только видео, плюс аудио. Такой канал недостижим на типичном железе и его аренде — это не вопрос выбора сервера мощнее, это упирается в канал и его стоимость у хостера.
Спасает лимит плиток на экране (настройка инстанса «Максимум плиток на
странице», 25/16/9/4, с релиза 0.0.21): он ограничивает число подписок сверху
независимо от числа камер — min(камер, лимит) × (участников − 1). При лимите
16 и том же собрании: 16 × 74 = 1184 подписки × 150 кбит/с (все 16 видны
одновременно, без пагинации) ≈ 178 Мбит/с только видео — втрое меньше, чем
без лимита, но всё ещё требует железа заметно больше базового пресета (3+ ядра
LiveKit по формуле). Лимит делает профиль реалистичным, не дешёвым. Тот же
эффект даёт «Потолок качества публикации» (720p/360p/180p, тот же релиз) —
режет битрейт публикации у источника, а не только у подписчика.
Если и это не помогает — речь уже не про один сервер, а про горизонтальное масштабирование LiveKit-кластера, вне рамок этого документа.
Входящая полоса и канал клиента — отдельная история
Таблица выше — исходящая полоса сервера (каждому подписчику отдельная копия), она и есть главный параметр: растёт с числом участников и подписок.
Входящая полоса (от клиентов к серверу) на порядок меньше: она равна сумме
битрейтов публикуемых потоков — камер × ~0.3–1.5 Мбит/с (зависит от «Потолка
качества публикации», 0.0.21) — и не умножается на число зрителей. Для
собрания на 75 человек с 15 камерами это 4.5–22.5 Мбит/с входящих — заметно
меньше 182 Мбит/с исходящих, узким местом почти никогда не становится.
Отдельно — канал самого клиента, не сервера. Офис, откуда заходит половина участников совещания, может упереться в свой исходящий/входящий канал раньше, чем сервер упрётся в свой. Серверный сайзинг эту часть не решает — это забота сетевой инфраструктуры на стороне участников.
Оговорка про канал и его стоимость
На реалистичных профилях (кроме экстремальных, см. выше) узким местом оказывается почти всегда не CPU — оба реальных замера показали комфортный запас (1.6–1.83 ядра из 4) — а исходящая полоса и её стоимость у хостера. Большинство тарифов VPS считают трафик либо лимитом с доплатой за перебор, либо по 95-му перцентилю канала; при планировании крупных конференций сверяйтесь с тарифом хостера на трафик/канал, а не только с числом ядер и объёмом RAM.
Как посчитать под свой сценарий
- Оцените участников (N), долю с камерой, число одновременно активных микрофонов.
подписок = камер × (N − 1); если планируете включить лимит плиток —min(камер, лимит) × (N − 1).- Выберите битрейт на подписку по разделу «Формула» (450 / 150 / 100 кбит/с) в зависимости от того, помещаются ли все камеры на одну страницу.
видео = подписок × битрейт,аудио = микрофонов × N × 40 кбит/с,полоса = видео + аудио.ядер CPU ≈ max(2, ⌈полоса ÷ 90⌉) + 1–2на остальной стек.- RAM — 4 ГБ база, не растёт заметно с этим масштабом участников (растёт с выбранным уровнем AI, см. ADR-004, если он используется).
- Сверьте полосу с тарифом хостера на трафик/канал — часто это упрётся раньше железа.
Что может измениться
⚠️ Коэффициент «90 Мбит/с на ядро» и оба якорных замера сняты до перевода
LiveKit с диапазона UDP-портов на rtc.udp_port (задача «Сеть LiveKit», релиз
0.0.20, задеплоено 02.08.2026) — до этой правки медиатрафик на хосте шёл через
процессы docker-proxy (userland-прокси Docker). Сама оптимизация меняет путь
пакетов на хосте, а не логику LiveKit, поэтому полоса из таблиц, скорее всего,
не изменится, а запас по CPU/сети хоста на практике может оказаться больше
указанного здесь. Новый нагрузочный тест с реальными участниками после этой
оптимизации пока не проводился — числа в этом документе консервативны и не
переоценивают требуемое железо, но при появлении нового замера на текущей
сети коэффициенты стоит пересчитать.
Смотрите также
- capacity.md — синтетический нагрузочный тест SFU (
lk load-testна dev-Mac) и формула по CPU для верхней оценки ёмкости узла; используйте вместе с этим документом, если нужна методика для собственного повторного теста. - install.md, hardware-profiles.md, ADR-004 — сайзинг под AI (транскрибация/суммаризация), отдельно от медиа.
- monitoring.md — как снять реальные цифры со своего сервера (CPU/RAM/сеть по контейнерам, Grafana).
- DEPLOYMENT.md — TURN, порты, что открыть в файрволе под медиа-трафик.