Тюнінг хостинг-сервера: 12 параметрів, які 80% адмінів залишають «за замовчуванням» - і дарма
Уявіть, що ви купили спортивний автомобіль, але їздите на ньому виключно в режимі «еко». Двигун на 400 конячних сил тихо скиглить під капотом, а ви дивуєтесь, чому вас обганяє кожна друга «Шкода». Саме так виглядає більшість хостинг-серверів у продакшені: потужне залізо, стандартні конфіги, жалюгідна продуктивність. Я бачив сервери з 64 ГБ RAM, які задихались на 200 одночасних з'єднаннях - просто тому, що ніхто не заглянув у налаштування глибше, ніж панель керування хостингу.
Ця стаття - не про базове «встановіть Linux і запустіть Apache». Вона для тих, хто вже має робочий сервер, але хоче витиснути з нього максимум. Без магії, без маркетингового туману - тільки конкретні параметри, які реально впливають на швидкість, стабільність і безпеку.
Чому дефолтні конфіги - ворог вашого проєкту
Розробники серверного софту - розумні люди. Але вони не знають вашого проєкту. Дефолтні налаштування MySQL, Nginx, PHP-FPM розраховані на максимальну сумісність, а не на максимальну продуктивність. Це як костюм з магазину «для всіх розмірів» - вдягнути можна, виглядати добре - ні.
Кожен сервер потребує індивідуального тюнінгу під конкретне навантаження. Інтернет-магазин на WooCommerce і API-бекенд для мобільного додатку - це два абсолютно різних профілі навантаження. А стандартний конфіг - один на всіх.
Ось реальний приклад. Клієнт скаржився на повільний сайт. Сервер - VPS з 8 ГБ RAM, SSD, 4 ядра. Начебто достатньо для WordPress-магазину з 2000 товарів. Проблема? max_connections у MySQL стояв на 151 (дефолт), innodb_buffer_pool_size - 128 МБ. На сервері з 8 гігабайтами оперативки! Після тюнінгу час завантаження сторінки впав з 4.2 до 1.1 секунди. Без жодного апгрейду залізної частини.

Веб-сервер: Nginx проти Apache - і третій варіант, про який забувають
Холівар Nginx vs Apache давно набрид усім. Але практика показує цікаву річ: найкращий результат часто дає зв'язка обох. Nginx як фронтенд-проксі обробляє статику і SSL-терминацію, Apache з mod_php або PHP-FPM працює на бекенді. Це не компроміс - це архітектурне рішення.
Ключові параметри Nginx, які варто змінити одразу:
- worker_processes - виставляйте рівно за кількістю ядер CPU (або
auto) - worker_connections - 2048-4096 замість стандартних 768
- gzip_comp_level - значення 4-5 дає оптимальний баланс стиснення і навантаження на CPU
- keepalive_timeout - 15-20 секунд, а не 65 за замовчуванням (менше витрат на утримання з'єднань)
- client_max_body_size - підлаштуйте під ваші потреби, особливо якщо є завантаження файлів
Третій варіант, який дедалі частіше з'являється у серйозних проєктах - OpenLiteSpeed. Безкоштовна версія LiteSpeed з підтримкою .htaccess, вбудованим кешем і продуктивністю, що подекуди перевершує Nginx. Якщо ваш проєкт на WordPress - варто спробувати серйозно.
PHP-FPM: маленькі цифри з гігантським впливом
PHP-FPM - це майстерня, де реально «варяться» ваші сторінки. І тут стандартні налаштування можуть бути відверто шкідливими.
| Параметр | Дефолт | Рекомендація (VPS 4-8 ГБ RAM) | Що робить |
|---|---|---|---|
| pm | dynamic | ondemand або static | Режим керування пулом процесів |
| pm.max_children | 5 | 20-40 (залежно від RAM) | Максимум одночасних PHP-процесів |
| pm.max_requests | 0 (безліч) | 500-1000 | Перезапуск воркера після N запитів (проти витоку пам'яті) |
| memory_limit | 128M | 256M (під ваш додаток) | Ліміт пам'яті на один процес |
| opcache.memory_consumption | 128 | 256 | Пам'ять для кешу скомпільованого PHP-коду |
| opcache.revalidate_freq | 2 | 60 (на продакшені) | Як часто перевіряти зміни у файлах |
Формула для розрахунку pm.max_children проста: візьміть доступну RAM (за мінусом ОС, MySQL, Nginx), поділіть на середнє споживання одного PHP-процесу (зазвичай 30-60 МБ). Маєте 4 ГБ «чистими»? При 50 МБ на процес - це 80 воркерів максимум. Але залишіть запас - ставте 50-60.
«Більшість проблем з продуктивністю PHP-додатків вирішуються не рефакторингом коду, а правильним налаштуванням OPcache і FPM pool. Це перше, куди варто дивитись.» - Nikita Popov, розробник ядра PHP

MySQL/MariaDB: де ховається 70% вашого гальмування
Якщо ваш сайт працює з базою даних (а він працює), то MySQL - найімовірніша причина повільності. І ось чому: дефолтний innodb_buffer_pool_size у 128 МБ - це як кеш-пам'ять калькулятора для бази на кілька гігабайт.
Що міняти в першу чергу:
- innodb_buffer_pool_size - виділіть 50-70% від доступної RAM (якщо сервер тільки під MySQL). На спільному сервері з PHP - 25-40%
- innodb_log_file_size - 256M-1G замість дефолтних 48M. Це прискорить запис
- max_connections - рахуйте реально: pm.max_children × кількість SQL-з'єднань на запит + 10-20% запасу
- query_cache_type - вимкніть (= 0) на MySQL 5.7+ / MariaDB 10.2+. Так, вимкніть. У сучасних версіях він приносить більше шкоди, ніж користі через mutex contention
- tmp_table_size / max_heap_table_size - збільшіть до 64-256M, щоб тимчасові таблиці не скидались на диск
- slow_query_log - увімкніть обов'язково. Встановіть
long_query_time = 1і аналізуйте
Порада, яка зекономить вам дні дебагу: встановіть MySQLTuner - скрипт, який аналізує вашу конфігурацію і дає конкретні рекомендації після кількох годин роботи сервера під навантаженням.
Ядро Linux: sysctl-магія, яку ігнорують навіть досвідчені адміни
Операційна система - фундамент, на якому стоїть весь ваш стек. І Linux за замовчуванням налаштований під «середнього» користувача, а не під веб-сервер з тисячами з'єднань.
Критичні параметри /etc/sysctl.conf:
- net.core.somaxconn = 65535 - максимальна черга з'єднань (дефолт 128 - катастрофічно мало)
- vm.swappiness = 10 - мінімізуємо використання swap (дефолт 60 - сервер почне «свопити» задовго до реальної нестачі RAM)
- net.ipv4.tcp_tw_reuse = 1 - повторне використання TIME_WAIT з'єднань
- fs.file-max = 2097152 - максимум відкритих файлових дескрипторів
Також не забудьте перевірити ліміти у /etc/security/limits.conf. Я зустрічав сервери, де Nginx не міг відкрити більше 1024 файлів одночасно - просто тому, що ніхто не подивився на ulimit -n.
Моніторинг: тюнінг без даних - це гадання на кавовій гущі
Ви можете налаштувати все ідеально. Один раз. А через місяць трафік зросте вдвічі, і всі ваші красиві конфіги перестануть працювати. Тому моніторинг - не «бонус», а обов'язковий елемент будь-якого серверного тюнінгу.
Мінімальний набір для серйозного проєкту:
- Netdata - реалтайм-моніторинг у браузері, ставиться за 30 секунд, показує сотні метрик. Безкоштовний
- Grafana + Prometheus - для тих, кому потрібні кастомні дашборди і алерти. Складніше, але набагато потужніше
- Slow query log + pt-query-digest - аналіз повільних SQL-запитів. Без цього оптимізація бази - стрільба наосліп
Мінімум, що ви маєте відстежувати постійно: CPU load average, використання RAM (з розбивкою на cache/buffer/actual), IOPS дискової підсистеми, кількість активних з'єднань до веб-сервера і БД, час відповіді PHP-FPM.
Правило, яке рятує від нічних дзвінків: налаштуйте алерти при 70% завантаженості будь-якого ресурсу. Не при 90% - буде пізно. Сімдесят відсотків - це ваш жовтий сигнал світлофора.
Безпека як частина продуктивності
Дивний заголовок? Зовсім ні. Зламаний сервер - повільний сервер. Криптомайнер у процесах з'їдає CPU. Ботнет-трафік забиває канал. Тому базова безпека - це про продуктивність теж.
Швидкий чеклист після будь-якого налаштування:
- SSH тільки по ключах, пароль - вимкнений, порт - нестандартний
- Fail2ban для SSH, HTTP auth, поштових сервісів
- Автоматичні оновлення безпеки (
unattended-upgradesна Debian/Ubuntu) - Окремий юзер для кожного сайту/сервісу - ніколи не запускайте PHP від root
Один зламаний WordPress-плагін на спільному сервері може покласти всі сайти. Я бачив це. Не раз.
Тепер чесно запитайте себе: коли востаннє ви заглядали у конфіги свого сервера глибше, ніж панель cPanel? Якщо відповідь «ніколи» або «не пам'ятаю» - у вас на столі лежить безкоштовний прискорювач, який чекає, поки його увімкнуть. Питання лише в тому, зробите ви це сьогодні - чи після наступного падіння сайту в п'ятницю ввечері.