- Fundamenty konfiguracji workerów w kontekście hostingu
- Czym jest worker w serwerze www
- Jak hosting ogranicza liczbę workerów
- Model procesu żądania a znaczenie workerów
- Kluczowe parametry workerów w popularnych konfiguracjach hostingowych
- Apache (MPM prefork, worker, event)
- Nginx jako warstwa frontowa i reverse proxy
- PHP-FPM – najczęstsze miejsce konfiguracji na hostingu
- Serwery aplikacyjne (Python, Node.js i inne)
- Metody obliczania optymalnej liczby workerów
- Szacowanie zużycia pamięci na proces
- Uwzględnianie charakterystyki ruchu i aplikacji
- Prosty wzór na start i jego korekty
- Monitorowanie i reagowanie na objawy przeciążenia
- Praktyczne scenariusze konfiguracji limitu workerów na hostingu
- Mały serwis na hostingu współdzielonym
- Średni sklep internetowy z ruchem sezonowym
- Aplikacja z ciężkimi obliczeniami na serwerze VPS
- Skalowanie poziome a ograniczenia hostingu
Poprawna konfiguracja limitu workerów w serwerach www to jeden z kluczowych elementów stabilnego i wydajnego hostingu. Zbyt mało procesów roboczych powoduje wolne ładowanie stron i kolejki żądań, zbyt dużo – przeciąża CPU i pamięć RAM, prowadząc do błędów 5xx lub blokowania całego serwera. Umiejętne dobranie parametrów takich jak liczba workerów, maksymalna liczba połączeń czy limity pamięci pozwala lepiej wykorzystać zasoby, obsługiwać większy ruch oraz uniknąć losowych przestojów i nagłych limitów narzuconych przez dostawcę hostingu.
Fundamenty konfiguracji workerów w kontekście hostingu
Czym jest worker w serwerze www
Worker to proces lub wątek odpowiedzialny za obsługę żądań HTTP przychodzących do serwera www. W zależności od technologii możemy mieć do czynienia z workerami w Apache (MPM prefork, worker, event), Nginx, PHP-FPM, czy w serwerach aplikacyjnych dla Pythona lub Node.js. Każdy worker zużywa pewną ilość pamięci RAM, czasu procesora oraz może utrzymywać określoną liczbę połączeń.
W środowisku hostingu współdzielonego workerów nie kontrolujemy w pełni – część parametrów jest ustawiona globalnie przez administratora. Jednak w wielu planach hostingowych (szczególnie wyższych lub typu VPS/serwer dedykowany) można własnoręcznie ustawić limity dla takich elementów jak:
- liczba procesów PHP-FPM na konto lub domenę,
- liczba współbieżnych skryptów PHP,
- liczba połączeń do serwera www,
- limity CPU, RAM oraz I/O.
Rozumienie roli workera jest kluczowe: każdy worker to potencjał do obsługi kolejnego użytkownika, ale też koszt zasobów. Optymalizacja polega na znalezieniu punktu, w którym mamy wystarczająco dużo workerów, aby nie tworzyć kolejek, ale na tyle mało, aby nie przeciążać serwera i nie wchodzić w konflikty z limitami narzuconymi przez hosting.
Jak hosting ogranicza liczbę workerów
Na współdzielonych planach hostingowych ograniczenia workerów często realizowane są pośrednio, poprzez parametry takie jak:
- maksymalna liczba jednocześnie wykonywanych procesów PHP,
- limit pamięci dla całego konta,
- ograniczenie liczby procesów systemowych,
- limit CPU lub czasu wykonywania skryptów,
- ochrona przed nadużyciami (np. LVE, CloudLinux, cgroups).
Oznacza to, że gdy zwiększasz liczbę workerów w konfiguracji serwera aplikacyjnego (np. PHP-FPM), ale przekraczasz limity przypisane do konta, hosting zaczyna ubijać procesy lub ograniczać ich wydajność. Finalnie użytkownicy widzą błędy 500, 503, sporadyczne time-outy lub drastyczne spowolnienia.
Aby świadomie konfigurować limity workerów, trzeba rozumieć jak twój dostawca hostingu implementuje politykę zasobów. Wielu dostawców informuje o tym w panelu klienta: pokazuje maksymalny RAM, CPU, liczbę procesów oraz aktualne zużycie. To właśnie te wartości są punktem odniesienia przy ustawianiu liczby workerów w serwerach www i warstwie aplikacji.
Model procesu żądania a znaczenie workerów
Każde żądanie użytkownika przechodzi przez kilka warstw:
- serwer www (Nginx, Apache, LiteSpeed) – obsługuje połączenie HTTP,
- warstwa aplikacyjna (np. PHP-FPM, Python WSGI, Node.js) – realizuje logikę aplikacji,
- baza danych (MySQL, PostgreSQL) – obsługuje zapytania,
- cache (Redis, Memcached, OPcache) – przyspiesza odczyty danych i kodu.
Worker w serwerze www może być zajęty przez żądanie, które blokuje się na zapytaniu do bazy, na zewnętrznym API lub na powolnym module. Jeśli limit workerów jest zbyt niski, kolejne żądania muszą czekać, aż któryś z procesów się zwolni. Z kolei przesadnie wysoka liczba workerów może doprowadzić do sytuacji, w której każdy z nich blokuje się na zewnętrznym zasobie, a serwer wyczerpuje CPU i RAM, nie mając sił do obsługi nowych żądań.
Świadoma konfiguracja musi zatem uwzględniać nie tylko suchy parametr liczba_workerów, ale również charakter aplikacji: czy ma dużo operacji I/O, jak długo trwają zapytania do bazy, czy używa cache oraz jak bardzo jest zoptymalizowana pod kątem zużycia pamięci.
Kluczowe parametry workerów w popularnych konfiguracjach hostingowych
Apache (MPM prefork, worker, event)
Apache może działać w różnych trybach przetwarzania (MPM – Multi-Processing Module). Najczęściej spotykane to prefork, worker i event. W kontekście hostingu współdzielonego wciąż popularny jest prefork, często używany z modułem mod_php. W nowszych i bardziej wydajnych środowiskach stosuje się MPM event wraz z PHP-FPM.
Podstawowe parametry, z którymi spotkasz się w konfiguracji Apache, to m.in.:
- StartServers – liczba procesów startowych,
- MinSpareServers / MaxSpareServers – minimalna i maksymalna liczba wolnych procesów,
- MaxRequestWorkers (dawniej MaxClients) – maksymalna liczba jednoczesnych żądań,
- ServerLimit – górny limit procesów, który musi być ≥ MaxRequestWorkers.
W hostingach współdzielonych dostęp do tych parametrów zwykle jest ograniczony, ale mają one bezpośredni wpływ na to, ile jednoczesnych połączeń może zostać obsłużonych przez serwer. MaxRequestWorkers to faktyczny limit równoczesnych żądań; jeśli ruch przekracza tę wartość, nowe żądania będą czekały w kolejce lub użytkownik zobaczy błąd.
Aby dobrać sensowną wartość, trzeba oszacować pamięć zużywaną przez pojedynczy proces. Przykładowo, jeśli jeden worker Apache z mod_php zużywa około 60 MB RAM, a serwer (lub przydział na hostingu) oferuje 2 GB RAM dostępne dla Apache, to:
2 GB / 60 MB ≈ 34 procesy
Od tej wartości trzeba odjąć bufor na system i inne procesy, więc realny MaxRequestWorkers może wynosić na przykład 20–25. Jest to bardzo uproszczony model, ale pokazuje zależność między pamięcią, a liczbą workerów.
Nginx jako warstwa frontowa i reverse proxy
Nginx opiera się na modelu asynchronicznym i wykorzystuje niewielką liczbę procesów roboczych, obsługujących wielu klientów w ramach jednego procesu. Typowe parametry konfiguracyjne to:
- worker_processes – liczba procesów worker, zwykle dostosowana do liczby rdzeni CPU,
- worker_connections – maksymalna liczba połączeń na worker,
- keepalive_timeout – czas utrzymania połączenia,
- worker_rlimit_nofile – limit otwartych plików (pośrednio połączeń).
W przeciwieństwie do Apache, w Nginxie dużą rolę odgrywa właściwe ustawienie worker_connections i zarządzanie połączeniami keep-alive. Gdy Nginx jest tylko frontem, a logika aplikacji jest obsługiwana przez PHP-FPM lub inny backend, nadmierne zwiększenie worker_connections może spowodować, że backend zostanie zalany żądaniami i zabraknie mu procesów do obsługi.
W hostingach współdzielonych zazwyczaj nie masz bezpośredniego dostępu do pełnej konfiguracji Nginxa, ale możesz wpływać na nią fragmentarycznie (przez pliki konfiguracyjne w katalogu domeny lub za pomocą panelu). Warto pamiętać, że:
- zbyt wysokie keepalive_timeout utrzymuje połączenia otwarte zbyt długo,
- zbyt niskie – powoduje częste ponowne negocjacje połączeń i większą liczbę żądań.
Optymalna konfiguracja musi balansować między liczbą jednoczesnych odwiedzających a dostępnymi zasobami backendu, do którego Nginx przekazuje żądania.
PHP-FPM – najczęstsze miejsce konfiguracji na hostingu
W większości współczesnych hostingów obsługujących PHP, użytkownik ma dostęp do konfiguracji PHP-FPM, przynajmniej w podstawowym zakresie. Kluczowe parametry znajdują się w sekcji pm (process manager) i obejmują:
- pm – tryb zarządzania procesami (static, dynamic, ondemand),
- pm.max_children – maksymalna liczba procesów roboczych PHP-FPM,
- pm.start_servers – liczba procesów tworzonych podczas startu (tryb dynamic),
- pm.min_spare_servers / pm.max_spare_servers – minimalna i maksymalna liczba wolnych procesów (dynamic),
- pm.max_requests – liczba żądań obsługiwanych przez proces zanim zostanie zrestartowany.
Najważniejszą wartością jest pm.max_children, czyli faktyczny limit jednocześnie wykonywanych skryptów PHP. Źle ustawiona wartość tego parametru potrafi zabić nawet bardzo szybki hosting:
- zbyt niska wartość – każdy kolejny użytkownik musi czekać, rośnie TTFB i czas ładowania strony,
- zbyt wysoka wartość – serwer wchodzi w silny swap lub przekracza limity RAM, co prowadzi do błędów 500/502/503.
Dobór pm.max_children musi więc wynikać z analizy: ile pamięci zajmuje pojedynczy proces PHP-FPM oraz ile realnie RAM mamy do dyspozycji (nie mylić z całkowitą pamięcią serwera – na hostingu współdzielonym otrzymujesz tylko wycinek).
Serwery aplikacyjne (Python, Node.js i inne)
W przypadku aplikacji pisanych w Pythonie (Django, Flask) lub Node.js, konfiguracja workerów często odbywa się w serwerach takich jak Gunicorn, uWSGI czy wbudowane proces managery. Przykładowo, w Gunicornie możesz określić liczbę workerów poprzez parametr workers, często dobierany według wzoru:
liczba_workerów = 2 × liczba_rdzeni_CPU + 1
To jednak tylko punkt startowy. Na hostingu współdzielonym ogranicza cię nie tylko CPU, ale przede wszystkim pamięć przydzielona na aplikację. Podobnie jak w PHP-FPM, każdy worker zużywa pewien stały przydział RAM; gdy przekroczysz całość dostępnych zasobów, hosting zaczyna obcinać procesy. Dlatego przy podejściu wzorowym trzeba uwzględnić realny limit pamięci i zmierzyć ile zajmuje pojedynczy worker pod typowym obciążeniem.
Metody obliczania optymalnej liczby workerów
Szacowanie zużycia pamięci na proces
Podstawą poprawnego ustawienia limitu workerów jest znajomość zużycia pamięci przez pojedynczy proces. Na VPS lub serwerze dedykowanym można to łatwo zmierzyć:
- wywołując polecenia systemowe (np. ps, top, htop),
- monitorując zużycie w czasie testów obciążeniowych,
- analizując logi i statystyki z panelu hostingowego.
Przykładowa procedura dla PHP-FPM:
- uruchom stronę testową i wygeneruj ruch (np. za pomocą narzędzia ab, JMeter, k6),
- sprawdź w top/htop ile pamięci używają procesy php-fpm,
- zanotuj średnią wartość RSS (Resident Set Size) dla kilku procesów,
- dodaj margines bezpieczeństwa (np. 10–20%) dla zmian obciążenia.
Załóżmy, że pojedynczy proces PHP-FPM zużywa średnio 80 MB RAM. Jeśli na koncie hostingowym masz dostępne 2048 MB pamięci, ale 512 MB chcesz zostawić na Apache/Nginx i inne procesy, to dla PHP-FPM pozostaje około 1536 MB. Maksymalna liczba workerów:
1536 MB / 80 MB ≈ 19
Dodając bufor bezpieczeństwa, można ustawić pm.max_children na poziomie 15–17. To nie jest idealne wyliczenie, ale wystarczająca baza wyjściowa, którą można później korygować na podstawie realnego obciążenia.
Uwzględnianie charakterystyki ruchu i aplikacji
Suche liczby niewiele znaczą bez kontekstu tego, jak zachowuje się aplikacja i jaki ruch generują użytkownicy. Główne czynniki to:
- średni czas generowania strony – im dłużej trwa, tym więcej workerów potrzebujesz, aby obsłużyć ten sam ruch,
- rodzaj operacji – aplikacja CPU-bound (intensywne obliczenia) kontra I/O-bound (czekanie na bazę, API, pliki),
- charakter ruchu – ciągły, równomierny versus nagłe piki (np. kampania marketingowa),
- cache – stopień wykorzystania mechanizmów cache’ujących (OPcache, cache obiektowy, HTTP Cache).
Dla aplikacji intensywnie korzystających z bazy danych, które często czekają na odpowiedź, większa liczba workerów może być uzasadniona, bo wiele z nich i tak czeka, a nie zużywa w tym czasie w pełni CPU. Jednak i tu ograniczeniem pozostaje pamięć – każdy process wciąż rezerwuje swój przydział RAM.
Warto przeprowadzić testy obciążeniowe z różną liczbą workerów (np. 5, 10, 15, 20) i sprawdzić:
- średni i maksymalny czas odpowiedzi,
- liczbę błędów (5xx, time-out),
- zużycie CPU i RAM w panelu hostingowym,
- stabilność (czy procesy nie są ubijane przez system).
Wyniki takich testów pozwalają namierzyć punkt, w którym dalsze zwiększanie workerów nie przynosi już korzyści, a zaczyna generować niestabilność.
Prosty wzór na start i jego korekty
Dla wielu praktycznych zastosowań można zastosować uproszczony schemat wyznaczania liczby workerów:
- krok 1: zmierz średnie zużycie RAM na proces (np. 80 MB),
- krok 2: ustal budżet pamięci przeznaczony na daną usługę (np. 1500 MB),
- krok 3: oblicz maksymalną liczbę procesów: budżet / zużycie (np. 1500 / 80 ≈ 18),
- krok 4: zastosuj bufor 20–30% i zaokrąglij w dół (np. 12–14),
- krok 5: przetestuj pod ruchem i obserwuj logi oraz metryki,
- krok 6: delikatnie podnoś lub obniżaj liczbę workerów, aż osiągniesz stabilny kompromis.
Taki proces iteracyjny jest znacznie skuteczniejszy niż ślepe przyjmowanie teoretycznych wzorów. Każdy hosting ma inną architekturę, inne zabezpieczenia, a aplikacje różnią się zużyciem zasobów nawet w obrębie tego samego CMS-a (np. WordPress z różnymi zestawami wtyczek).
Monitorowanie i reagowanie na objawy przeciążenia
Nawet najlepiej policzona konfiguracja workerów wymaga stałego monitoringu. W środowisku hostingowym szczególnie warto obserwować:
- komunikaty o przekraczaniu limitów zasobów w panelu (RAM, CPU, IO),
- wzrost liczby błędów 500/502/503,
- wzrost średniego TTFB i czasu renderowania strony,
- logi serwera (error_log, logi PHP-FPM, logi Apache/Nginx).
Typowe symptomy tego, że limit workerów jest ustawiony niewłaściwie, to:
- nagłe skoki obciążenia CPU po zwiększeniu liczby workerów,
- nagłe ubijanie procesów przez system po osiągnięciu określonego pułapu pamięci,
- kolejki żądań i rosnące czasy odpowiedzi mimo niskiego średniego obciążenia CPU.
W takich sytuacjach najczęściej konieczne są drobne korekty: zmniejszenie liczby workerów, skrócenie czasu keep-alive, zmiana trybu zarządzania procesami w PHP-FPM albo przeprojektowanie najbardziej zasobożernych fragmentów aplikacji (np. optymalizacja zapytań SQL lub wykorzystanie cache).
Praktyczne scenariusze konfiguracji limitu workerów na hostingu
Mały serwis na hostingu współdzielonym
Załóżmy, że prowadzisz niewielki serwis oparty na WordPressie, hostowany na tanim planie współdzielonym. Dostawca oferuje:
- 1–2 rdzenie CPU dzielone z innymi użytkownikami,
- 1–2 GB RAM przydzielone do konta,
- limit jednoczesnych procesów PHP, np. 10,
- automatyczne ograniczanie zasobów przy przeciążeniu.
W takim scenariuszu kluczowe jest, aby nie ustawiać liczby workerów na maksymalne wartości deklarowane w panelu. Zamiast konfigurować pm.max_children na 10, rozsądniej będzie ustawić 4–6 i postawić na optymalizację aplikacji:
- włączenie OPcache i cache stron (plugin cache’ujący w CMS),
- minimalizacja liczby ciężkich wtyczek,
- ograniczenie liczby jednoczesnych zapytań AJAX,
- kompresja i optymalizacja obrazów.
Dobrze zoptymalizowany WordPress jest w stanie obsłużyć zaskakująco duży ruch przy niewielkiej liczbie workerów, bo większość odpowiedzi może pochodzić z cache, bez generowania ciężkich zapytań do bazy za każdym razem. W takim przypadku podniesienie liczby workerów ponad rozsądny poziom najczęściej tylko zwiększa ryzyko przekroczenia limitów RAM.
Średni sklep internetowy z ruchem sezonowym
Drugi scenariusz to sklep internetowy średniej wielkości, korzystający z hostingu wyższego planu lub małego VPS zarządzanego przez dostawcę. Sklep doświadcza dużych wahań ruchu, np. podczas wyprzedaży, świąt czy kampanii marketingowych. Zasoby mogą wyglądać tak:
- 4 rdzenie CPU,
- 8 GB RAM,
- możliwość konfiguracji Apache/Nginx i PHP-FPM,
- zabezpieczenia anty-DDoS, cache HTTP, CDN.
W tym przypadku warto zastosować bardziej agresywną konfigurację workerów, ale opartą na twardych danych. Zakładając, że pojedynczy proces PHP-FPM zużywa około 120 MB, a na warstwę PHP chcesz przeznaczyć 4 GB RAM, dostajesz:
4096 MB / 120 MB ≈ 34 procesy
Po uwzględnieniu bufora i innych procesów, można ustawić pm.max_children w przedziale 20–26. Jednocześnie należy zadbać, by:
- Nginx lub Apache nie przekazywały więcej żądań równocześnie niż PHP-FPM może obsłużyć,
- baza danych miała odpowiednio ustawione limity połączeń i pamięci,
- mechanizmy cache (np. Redis) przejmowały jak najwięcej ruchu od bazy.
W okresach wzmożonego ruchu monitorowanie jest szczególnie ważne – jeśli podczas kampanii widzisz rosnącą liczbę błędów 502/503, to znak, że backend (PHP-FPM lub baza) nie nadąża i trzeba albo podnieść limity, albo zwiększyć zasoby planu hostingowego.
Aplikacja z ciężkimi obliczeniami na serwerze VPS
Trzeci przykład to niestandardowa aplikacja, która wykonuje ciężkie obliczenia (np. generowanie raportów, przetwarzanie obrazów, analiza danych) na serwerze VPS z dedykowanymi zasobami. Tu liczba workerów powinna być ściśle związana z liczbą rdzeni CPU i charakterem obciążenia.
Jeśli aplikacja jest głównie CPU-bound i ma 4 rdzenie do dyspozycji, sensowne może być ustawienie liczby workerów aplikacyjnych na 4–6. Większa liczba spowoduje głównie przełączanie kontekstu między procesami i może zmniejszyć ogólną wydajność. W tym wypadku kluczowe są:
- profilowanie kodu w celu zmniejszenia zużycia CPU,
- kolejkowanie zadań ciężkich (np. za pomocą Redis + worker queue),
- rozdzielenie ruchu użytkowników od zadań batch’owych (osobne procesy, inne priorytety).
Limity workerów w serwerze www (Nginx/Apache) powinny być tak ustawione, aby nie przepuszczać więcej żądań obliczeniowo kosztownych niż aplikacja jest w stanie obsłużyć w rozsądnym czasie. W praktyce oznacza to często niższą liczbę workerów, niż sugerują domyślne ustawienia.
Skalowanie poziome a ograniczenia hostingu
W wielu momentach możesz dojść do ściany: dalsze podnoszenie liczby workerów na jednym serwerze nie daje realnej poprawy, bo ograniczeniem stają się twarde limity hostingu lub architektura aplikacji. Wtedy warto rozważyć:
- sklonowanie aplikacji na kilka instancji (np. kilka kont hostingowych lub kilka serwerów VPS),
- zastosowanie load balancera równoważącego ruch,
- wykorzystanie CDN w celu odciążenia serwera z obsługi statycznych zasobów,
- przeniesienie najbardziej wymagających elementów (np. bazy danych) na osobną maszynę.
Skalowanie poziome nie zastępuje konfiguracji workerów, ale zmienia sposób myślenia: zamiast maksymalizować limity na jednym węźle, koncentrujesz się na równomiernym rozłożeniu ruchu i zapewnieniu, że każdy węzeł ma rozsądnie dobraną liczbę procesów roboczych.