Гипотезу про запись звонков проверили замером - она оказалась неверной
Запись звонков в продукте делает отдельный под: внутри headless Chrome открывает страницу встречи и пишет с неё картинку. На тяжёлых встречах он то упирался в потолок процессора, то падал по памяти, а пользователи видели одно - запись оборвалась.
Ходовая гипотеза в команде звучала логично: переключить страницу записи в режим докладчика, показывать одного говорящего вместо сетки на девять камер, и нагрузка упадёт. Прежде чем это писать, я собрал замерный стенд: несколько сценариев встречи, одинаковая длительность, снятие процессора и памяти пода по каждому прогону.
Что показали цифры
Обычная встреча укладывалась в лимиты с запасом: пик процессора около 2,8 ядра при лимите в 4, память 1-2 ГБ, ни одного перезапуска. Тяжёлая сцена разгоняла под до 7,7 ядра и 5,4 ГБ, и на лимите памяти он получал OOM.
А вот режим докладчика ничего не спасал. Стоимость записи складывается из двух частей: постоянный энкод выходного потока плюс приём всех входящих дорожек. Первая часть не зависит от того, что нарисовано на экране, вторая - от числа участников, а не от раскладки. Убрать сетку означало убрать только отрисовку, самую дешёвую часть счёта.
Настоящий рычаг нашёлся в другом месте: не подписываться на дорожки, которые в запись не попадают. Я это сделал, и запись сломалась - при выборочной подписке терялись куски, которые как раз нужны. Откатил ревертом. В релиз ушла только безопасная часть оптимизации, а рискованная осталась в ветке с описанием, почему она не работает.
Побочная находка, которая оказалась важнее
Пока разбирался, обнаружил вещь, за которой никто не шёл. Страница записи переиспользовала боевую сетку участников, а у той есть предел в 16 плиток на страницу и нет пагинации в режиме записи. То есть на встрече в 50 человек в файл попадали первые шестнадцать, а остальные молча отсутствовали.
Это уже не производительность, а корректность: люди получали запись, которая выглядит целой, но целой не является. Нашлось только потому, что я лез в код страницы записи с замерами, а не с готовым ответом.
Чему это меня научило
Красивая гипотеза стоит ровно столько, сколько стоят замеры под ней. Если бы я сразу пошёл писать режим докладчика, работа заняла бы несколько дней и не дала бы ничего - а объяснить, почему «оптимизация не помогла», было бы нечем.