Двадцать аккаунтов в CRM ничего не сообщают о нагрузке. Эти двадцать человек могут молча просидеть день в открытых карточках, изредка нажимая «сохранить», а могут в десять утра одновременно открыть список клиентов с тремя фильтрами, сортировкой по дате последнего контакта и выгрузкой в таблицу. Для сервера это два разных мира, хотя в списке пользователей написано одно и то же число. Поэтому вопрос «какой VPS нужен для двадцати сотрудников» стоит заменить другим: какие действия они совершают, как часто и что из этого самое дорогое.
Ниже разобрано, как превратить это в измеримую задачу: описать профиль операций, разделить нагрузку между веб-приложением, базой и диском, понять, где живут дорогие запросы, и только потом сопоставить результат с тарифом. Двадцать здесь — размер команды в нашем сценарии, а не норматив ёмкости: из него нельзя вывести гигабайты или ядра, их даёт только замер на ваших данных.
Профиль операций вместо профиля пользователей
Начните с короткого списка того, что сотрудники реально делают. Для большинства CRM он укладывается в пять пунктов:
- Открытие карточки клиента или сделки со связанными записями: звонки, задачи, письма, комментарии.
- Поиск по имени, телефону, почте или названию компании.
- Список с фильтрами и сортировкой: «мои открытые сделки», «клиенты без активности 30 дней».
- Отчёт или сводка: воронка, выручка за период, нагрузка менеджеров.
- Вложение: загрузка договора или скана, скачивание файла.
К этому добавляется то, чего люди не видят: фоновые задачи. Рассылки, обработка входящей почты, напоминания, синхронизации и обслуживание по расписанию работают от имени системы и конкурируют с живыми пользователями за те же процессор и диск.
Теперь каждому пункту нужны два параметра: как часто он случается в рабочий день и сколько таких действий происходит одновременно в самый плотный интервал. Здесь полезно быть честным с собой. Карточку открывают сотни раз, и каждый раз это недорого. Тяжёлый отчёт строят раз в день, зато в планёрку или в конце месяца его запускают сразу несколько человек. Средняя нагрузка за сутки получится приятной, а мешать вам будет именно пик.
Реалистичные данные для пробы
Вторая половина профиля — объём данных. Пустая CRM с двадцатью пользователями летает на любом сервере, и вывод из такого теста бесполезен. Нужна пробная база, похожая на вашу будущую: сопоставимое число контактов, сделок, звонков и заметок, примерно такое же распределение полей. Если вы переезжаете, возьмите копию текущей базы. Если начинаете с нуля, сгенерируйте записи с разбросом: часть полей заполнена, часть пуста, у некоторых клиентов по сотне связанных событий, у большинства по три. Равномерные синтетические данные скрывают как раз те запросы, которые потом окажутся медленными.
Запас по росту тоже закладывайте в данные, а не в тариф «на вырост». Спросите себя, сколько записей будет через год-два, умножьте пробную базу и повторите замеры. Так вы увидите, где кривая начинает загибаться, и сможете принять решение по факту.
Три места, где нагрузка оседает
Когда профиль готов, его полезно разложить по трём «этажам» системы: веб-приложение, база данных и диск. У каждого свой характер, и ресурс VPS закрывает их по-разному.
Веб-приложение (в случае EspoCRM это PHP и веб-сервер) собирает страницу, проверяет права, формирует ответ. Его нагрузка растёт с числом одновременных запросов и чаще упирается в процессор и память на процесс. Открытие карточки и поиск в основном живут здесь, пока запрос к базе остаётся быстрым.
База данных отвечает за выборки, фильтры, сортировки, подсчёты и агрегаты для отчётов. Её нагрузка зависит не столько от числа пользователей, сколько от формы запроса и объёма таблицы. Один запрос по неиндексированному полю в большой таблице способен занять ядро и диск на заметное время, и тогда остальные ждут в очереди. Для базы важны память (чтобы горячие данные и индексы не вымывались), скорость диска и число ядер.
Диск принимает вложения, журналы, дампы резервных копий и обслуживает базу, когда данные не помещаются в память. Здесь различают два режима: много мелких обращений (база) и крупные последовательные операции (файлы, копирование). NVMe, о котором заявляет MAATRIX в описании VPS, помогает прежде всего в первом режиме, но он не отменяет вопроса, почему запросу вообще пришлось читать столько данных.
Практическая польза деления в том, что замер каждой операции из профиля можно привязать к своему этажу. Если карточка открывается медленно, а процессор базы простаивает, смотрите приложение. Если список тормозит, а загрузка базы упирается в потолок, дело в запросе. Если скачивание вложений тянется, а запросы быстрые, проверьте диск и сеть. Без такого разделения любая жалоба «CRM тормозит» заканчивается одинаково: «давайте возьмём тариф побольше».
Таблица измеряемых операций
Ниже рамка для вашего собственного теста. Столбец результатов намеренно пуст: цифры должны появиться из вашей пробной базы и вашего сервера, а не из чужого бенчмарка.
| Операция | Что задать в пробе | Что наблюдать | Где искать причину при медленном ответе |
|---|---|---|---|
| Открытие карточки | Карточки с малым и очень большим числом связанных записей, несколько открытий параллельно | Время ответа, загрузка процессора приложения | Число связанных выборок, права доступа, процессы приложения |
| Поиск | Типовые запросы: часть фамилии, телефон, название компании | Время ответа по мере роста базы | Поля, по которым идёт поиск, наличие индексов |
| Список с фильтром и сортировкой | Самые частые сохранённые фильтры, сортировка по разным полям | Время до первой страницы, нагрузка на базу | Индексы под фильтр и сортировку, подсчёт общего количества |
| Отчёт | Самый широкий период, запуск нескольких одновременно | Длительность, влияние на остальные операции | Агрегаты по большим таблицам, память базы, диск |
| Вложение | Загрузка и скачивание файлов типичного для вас размера, несколько параллельно | Скорость передачи, загрузка диска и сети | Диск, сеть, лимиты веб-сервера и PHP на размер загрузки |
| Фоновые задачи | Расписание в рабочие часы и обработка накопленной очереди | Задержка пользовательских операций во время задач | Пересечение задач с пиком, общий процессор и диск |
Последняя строка часто оказывается неожиданной. Каждая операция по отдельности может быть быстрой, а вместе они складываются: рассылка идёт, пока менеджеры строят отчёты. Поэтому один из тестов должен быть составным: запустите несколько операций из таблицы одновременно и посмотрите, как изменится время отклика обычных карточек. Это ближе к вашему реальному «тяжёлому интервалу», чем любая отдельная метрика.
Дорогой подсчёт, фильтр и сортировка
Самый показательный пример медленного места в CRM — список записей. Выглядит он безобидно: таблица на экране, двадцать строк на странице. Но чтобы показать её, система делает как минимум три работы: отбирает записи под фильтр, сортирует их и считает, сколько всего записей подошло, чтобы нарисовать «страница 1 из 340».
Документация EspoCRM отдельно предупреждает: полный подсчёт количества в больших списках может быть дорогим, и для этого предусмотрена возможность отключить показ общего числа записей (EspoCRM: Performance tweaking). Смысл понятен без подробностей реализации: чтобы назвать точное число, базе нужно пройти по всем подходящим строкам, а чтобы показать первую страницу, достаточно найти первые двадцать. Разница растёт вместе с таблицей. На пробной базе в тысячу записей вы её не заметите, на базе в сотни тысяч она станет главным тормозом списка.
Тот же источник связывает выбор индексов с тем, по каким полям вы фильтруете и сортируете, а также с отчётами и пользовательской настройкой CRM. Это важная мысль для тех, кто собирается кастомизировать систему: добавили своё поле, стали по нему фильтровать, и список медленно ползёт не потому, что сервер слаб, а потому, что база для этого поля вынуждена просматривать всю таблицу. Индекс — это заранее подготовленный порядок, позволяющий найти нужное без полного перебора. Какой именно индекс нужен, зависит от ваших фильтров, и тут помогает профиль операций: он подсказывает, какие поля вообще стоит рассматривать.
Как это проверить на пробе
Возьмите три-четыре самых частых фильтра ваших менеджеров и самую частую сортировку. Откройте соответствующие списки на пробной базе увеличенного объёма. Затем повторите то же самое с отключённым общим подсчётом (если он вам не нужен для работы) и сравните ощущения и время. Если разница заметная, у вас есть конкретное решение без смены тарифа. Если список всё равно медленный, смотрите на индексы под поля фильтра и сортировки. И лишь когда запрос честно написан и проиндексирован, а выборка всё равно упирается в память или диск, разговор переходит к ресурсам сервера.
Отдельно стоит отнестись к сохранённым фильтрам и отчётам, построенным «на все времена». Фильтр «все сделки за всю историю, сортировка по сумме» дороже, чем «сделки за квартал». Иногда самое дешёвое ускорение — договориться, что руководитель по умолчанию смотрит квартал, а не весь архив.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации Россия, США, Франция и Великобритания. Оплата картой РФ и по СБП.
Почему PHP preload не заменит работу с базой
Теперь разберём типичную ловушку. Администратор открывает руководство по производительности, видит упоминание предзагрузки PHP (preload) и решает, что вот оно, волшебное ускорение. Предзагрузка действительно относится к настройке PHP, и в этом нет ничего плохого. Но документация EspoCRM описывает её как меру, которая обычно не даёт большого выигрыша, и прямо указывает, что в CRM узким местом чаще бывает база данных (EspoCRM: Performance tweaking).
Почему так происходит, легко понять из разделения на этажи. Предзагрузка сокращает работу PHP по подготовке кода: приложение быстрее запускается и меньше тратит на загрузку классов. Это экономия на этаже веб-приложения. Но если пользователь ждёт четыре секунды, потому что база перебирает сто тысяч строк для сортировки по неиндексированному полю, то сэкономленные доли секунды на загрузке кода тонут в этих четырёх. Это как ускорять погрузку чемоданов, когда самолёт задерживается из-за диспетчера.
Практический вывод для EspoCRM-сценария такой. Сначала определите по таблице операций, на каком этаже теряется время. Если процессор приложения почти свободен, а база занята, настройки PHP не помогут, даже самые правильные. Работайте с индексами, с подсчётом количества, с тем, какие отчёты и фильтры вы разрешаете гонять по всей истории. Настройки PHP имеют смысл как дополнение, когда база уже в порядке, а приложение действительно упирается в процессор. И уж точно не стоит ради скорости ослаблять настройки надёжности базы данных, которые встречаются в разных руководствах: выигрыш в секундах не стоит риска потерять подтверждённые записи при сбое.
Когда ресурсы действительно нужны
Всё сказанное не отменяет простого факта: у любого запроса есть потолок, и после оптимизации он может оказаться выше возможностей слишком маленькой машины. Вопрос в порядке действий. Увеличение ресурсов разумно, когда вы можете назвать узкое место и объяснить, что именно оно решит.
- Памяти не хватает базе. Признак: запросы, которые быстро выполняются «в прогретом» состоянии, внезапно становятся медленными после простоя или при росте базы, а диск при этом активно читается. Больше памяти позволяет держать в ней рабочий набор данных и индексов.
- Не хватает ядер при параллельных отчётах. Признак: один отчёт идёт нормально, а три одновременных тянутся втрое дольше и забивают остальных. Здесь помогает больше vCPU, но сначала проверьте, не лечится ли это расписанием или упрощением отчёта.
- Диск не справляется с мелкими обращениями или копированием. Признак: высокая загрузка диска при низкой загрузке процессора, особенно во время резервного копирования или массовой загрузки вложений.
- Приложению не хватает процессов. Признак: процессор приложения упирается в потолок, а база свободна. Это единственный случай, где настройки PHP и число рабочих процессов выходят на первый план.
У каждого пункта своя «лекарственная форма». Больше памяти и быстрый диск закрывают базу, ядра закрывают параллельность, а правильный индекс не требует ни того ни другого. Если вы начнёте с тарифа и не поняли причины, есть риск заплатить за вдвое большую машину и получить тот же медленный список, потому что виноват был полный подсчёт или отсутствие индекса.
Как сопоставить результаты пробы с линейкой тарифов
У MAATRIX в публичном предложении есть линейка VPS на NVMe с AMD EPYC и root-доступом: Ba (1 vCPU, 2 ГБ RAM, 40 ГБ NVMe), Uab (2 vCPU, 4 ГБ, 80 ГБ), Heka (4 vCPU, 8 ГБ, 160 ГБ), Maat (8 vCPU, 16 ГБ, 240 ГБ) и Djed (16 vCPU, 32 ГБ, 320 ГБ). Эти цифры описывают состав машины, но не обещают, что на ней уместится конкретное число сотрудников: ёмкость определяется вашими данными и вашими сценариями.
Работать с линейкой удобно так. Разверните пробную CRM на разумной ступени, например на средней, прогоните таблицу операций и наблюдайте, какой ресурс упирается первым. Если процессор почти не загружен, а память кончается, нужна ступень с большим объёмом памяти, а не с большим числом ядер. Если всё укладывается с запасом, попробуйте ступень ниже и убедитесь, что составной тест тоже проходит. Такая проверка занимает часы, а не недели, поскольку, по публичному описанию, VPS создаётся автоматически через пару минут после оплаты. Оплата доступна картой РФ и через СБП, а локации в предложении перечислены UK, US, RU и FR; точные параметры и наличие образов проверяйте в форме заказа. Доступ root даёт возможность смотреть загрузку процессов и диска самостоятельно, а это и есть главный инструмент для привязки симптома к этажу.
Если же ваша картина другая и речь идёт не о двадцати, а о сотнях пользователей, с разными требованиями к размещению и изоляции, имеет смысл прочитать отдельный разбор: выделенный сервер в России для CRM на сотни пользователей.
Резервная копия как часть теста
Один из самых тяжёлых моментов для диска и базы — резервное копирование, и его стоит включить в пробу, а не откладывать. По документации EspoCRM, полная резервная копия включает файлы системы и дамп базы данных, а восстановление затрагивает файлы, права доступа, базу и проверку расписания cron; инструкции для контейнерной и обычной установки различаются (EspoCRM: Backup and restore).
Для оценки VPS из этого следуют два практических вопроса. Первый: сколько времени занимает создание дампа на вашей пробной базе и как это влияет на отклик во время работы? Если дамп идёт в рабочие часы и список клиентов начинает «задумываться», копию надо переносить на ночь, и это решение расписания, а не тарифа. Второй: сколько места занимают файлы и дамп вместе, и где копия хранится? Копия на том же диске, что и рабочая система, плохо защищает от потери этой системы, поэтому её место определяется отдельно. Среди подтверждённых свойств публичного предложения автоматические резервные копии во всех тарифах не значатся, так что вопрос копий лучше решать как собственную задачу и проверять восстановление на отдельной пробной установке, а не предполагать его наличие.
Заодно проверка восстановления проверяет вашу пробную базу: если после развёртывания копии списки открываются так же быстро, как и до неё, вы знаете, что скорость не зависела от случайного состояния кэша.
Как выглядит составной тест на практике
Пример условный, цифры в нём не результаты измерений, а способ организовать работу. Допустим, у компании двадцать сотрудников: десять менеджеров, пять сотрудников поддержки, три руководителя и два бухгалтера. Из разговора с командой выясняется, что самый тяжёлый интервал начинается в понедельник около десяти утра. Менеджеры открывают свои списки сделок, руководители строят воронку за квартал, а бухгалтеры выгружают документы по закрытым сделкам. Параллельно по расписанию обрабатывается входящая почта.
Тест строится вокруг этого интервала. Подготовьте пробную базу с объёмом, превышающим сегодняшний. Сделайте набор сценариев: десять параллельных открытий списков с типовым фильтром, три одновременные воронки за квартал, две выгрузки, несколько загрузок вложений и включённая фоновая обработка. Запустите всё вместе и параллельно открывайте обычные карточки руками, как это делал бы сотрудник. Записывайте, на каких операциях ощущается задержка, и смотрите на загрузку процессора, памяти и диска. Затем по таблице выше определите этаж, а по этажу — действие: индекс, отключение подсчёта, перенос отчёта на другое время, больше памяти, больше ядер.
Результат такого теста — не «нужен тариф такой-то», а понятная цепочка: этот отчёт при трёх одновременных запусках упирается в процессор базы, значит, либо запрещаем параллельный запуск по расписанию, либо берём ступень с большим числом ядер. Вторая часть вывода почти всегда дороже первой, и теперь вы знаете, что выбираете её сознательно.
Рабочий интервал вместо числа в списке
Вернёмся к началу. Двадцать пользователей — это ничего не говорящая цифра, пока вы не знаете, что они делают в самые напряжённые полчаса недели. Когда этот интервал описан, данные для пробы подобраны, а каждая операция привязана к своему этажу, выбор VPS перестаёт быть гаданием. Вы понимаете, что лечится индексом и настройкой списка, что лечится расписанием, а что действительно требует памяти, ядер или более быстрого диска.
Поэтому конфигурацию стоит выбирать под известный самый тяжёлый рабочий интервал, пройденный на реалистичной базе, и пересматривать при изменении этого интервала: пришёл новый отдел, появился новый отчёт, база выросла вдвое. Тогда вы повторяете тот же короткий тест и двигаетесь по линейке вверх или вниз осознанно, а не потому, что цифра в списке сотрудников изменилась.