Dlaczego Magento 2 działa wolno i co możesz wykluczyć w 15 minut?
Zanim wydasz od 4 000 do 12 000 PLN netto na zewnętrzny audyt techniczny Magento, zweryfikuj podstawowe wąskie gardła w konfiguracji środowiska, indeksach i modułach zewnętrznych. W 70% przypadków powolny sklep na Magento 2.4.7 (PHP 8.2 lub 8.3) nie wymaga przepisywania architektury, lecz naprawienia niespójnego cache, pętli w cronie lub błędnie napisanej wtyczki do integracji z ERP. Poniższa checklist pozwala Twojemu zespołowi technicznemu lub samodzielnemu administratorowi wyeliminować najbardziej powtarzalne awarie wydajnościowe bez płacenia agencji za oczywiste diagnozy.
Czy na pewno masz poprawnie skonfigurowany Varnish i Full Page Cache?
Domyślny mechanizm Built-in Cache w Magento 2 nie nadaje się na środowisko produkcyjne obsługujące więcej niż 10 zamówień na godzinę. Zapisuje dane na dysku serwera lub w Redis, co przy dynamicznym ruchu generuje narzut I/O i blokuje procesy PHP-FPM. Jeśli TTFB (Time to First Byte) dla stron kategorii przekracza 800 ms, pierwszym podejrzanym jest brak Varnisha lub unieważnianie całego cache'u przez pojedynczy błąd w kodzie layoutu.
Sprawdź nagłówki odpowiedzi HTTP w DevTools przeglądarki (zakładka Network -> Doc):
- X-Magento-Cache-Debug: Powinno zwracać
HIT. WartośćMISSprzy kolejnych odświeżeniach oznacza, że strona w ogóle się nie keszuje. - X-Varnish: Obecność dwóch identyfikatorów świadczy o poprawnym odpytaniu cache proxy.
- Cache-Control: Wartości
no-cache, privatena stronach produktów i kategorii to sygnał alarmowy.
Najczęstszy powód rozbijania FPC na stronach katalogu to atrybut cacheable="false" umieszczony w pliku default.xml lub layoutach bloków globalnych przez zewnętrzny moduł (częsta praktyka w starszych wtyczkach do banerów czy trackerów marketingowych). Jedna taka linijka w XML zamienia cały sklep w aplikację renderowaną w 100% z poziomu PHP.
# Szybka weryfikacja statusu cache z poziomu CLI:
bin/magento cache:status
# Wyszukanie zabójców FPC w modułach:
grep -rn 'cacheable="false"' app/code/ vendor/ | grep -v 'checkout' | grep -v 'customer'Jak sprawdzić, czy polskie moduły i integracje nie blokują bazy danych?
W polskich realiach e-commerce Magento rzadko działa w próżni. Typowy stos obejmuje integrację z Comarch ERP Optima, Subiekt GT / nexo, Baselinkerem, Allegro, kurierem InPost (ShipX) oraz bramkami płatności jak Przelewy24, PayU czy bramka BLIK. Błędy w tych integracjach potrafią zdusić bazę MySQL/MariaDB do zera.
U nas w projektach SISL regularnie trafiamy na sytuacje, w których synchronizator magazynowy z Subiekta wysyła zapytania UPDATE na tabelę cataloginventory_stock_item co 60 sekund w paczkach po 50 000 rekordów. Taka operacja nakłada blokady na wiersze (row-level locking), zatrzymując jednoczesne dodawanie produktów do koszyka i finalizację zamówień w checkout.
Zwróć uwagę na:
- Kolejkowanie KSeF i JPK: Nowe moduły przygotowane pod Krajowy System e-Faktur potrafią generować XML synchronicznie w momencie zmiany statusu zamówienia na Complete, blokując odpowiedź serwera dla klienta nawet na 4-6 sekund.
- Biała lista VAT i weryfikacja NIP: Zewnętrzne zapytania cURL do API Ministerstwa Finansów bez zdefiniowanego timeoutu (np. domyślne 30 sekund) potrafią zablokować wątki PHP-FPM, jeśli serwery rządowe mają opóźnienia.
- Webhooki InPost i Przelewy24: Brak asynchronicznego przetwarzania statusów przesyłek i płatności zmusza Magento do przeliczania reguł koszykowych i wysyłki maili transakcyjnych w wątku głównym webhooka.
Które komendy w CLI zdradzają problem z wydajnością w 3 minuty?
Zanim zaczniesz analizować profile xDebug czy instalować Blackfire (który kosztuje od 99 EUR miesięcznie w planie komercyjnym), wykonaj zestaw podstawowych poleceń z poziomu konsoli serwera:
# 1. Sprawdź stan indeksów
bin/magento indexer:status
# 2. Zweryfikuj zakleszczone procesy crona w bazie danych
mysql -e "SELECT job_code, status, created_at, executed_at FROM cron_schedule WHERE status = 'running' ORDER BY executed_at ASC LIMIT 10;"
# 3. Sprawdź rozmiar tabel z logami i sesjami
mysql -e "SELECT table_name, round(((data_length + index_length) / 1024 / 1024), 2) as 'Size in MB' FROM information_schema.TABLES WHERE table_schema = DATABASE() AND table_name IN ('cron_schedule', 'session', 'quote', 'search_query', 'customer_visitor');"Jeśli tabela cron_schedule przekracza 500 MB, mechanizm bin/magento cron:run spędza więcej czasu na przeszukiwaniu własnej kolejki niż na wykonywaniu zadań. Z kolei wiszące indeksy w trybie Update on Save blokują zapisywanie produktów z poziomu panelu administracyjnego (gdzie zapis pojedynczego SKU potrafi trwać ponad 20 sekund zamiast 400 ms).
Czy moduły od Amasty, Mirasvit lub MageWorx spowalniają sklep?
Wdrożenia oparte na kilkudziesięciu modułach komercyjnych często cierpią na tzw. plugin hell. Magento 2 wykorzystuje mechanizm interceptorów (Plugins: before, after, around). Metody typu around są szczególnie kosztowne pod kątem zużycia pamięci i stosu wywołań, ponieważ tworzą dodatkowe warstwy w łańcuchu wykonania PHP.
Pojedynczy plugin
aroundGetFinalPricez modułu promocji lub wielowalutowości, wykonujący zapytanie do bazy danych w pętli renderującej listing 48 produktów, potrafi wydłużyć generowanie bloku kategorii z 80 ms do 2,5 sekundy.
Jak to zdiagnozować bez płatnych narzędzi?
- Wyłącz podejrzany moduł w środowisku testowym za pomocą
bin/magento module:disable Vendor_ModuleName. - Przeładuj konfigurację i skompiluj kod:
bin/magento setup:upgrade && bin/magento setup:di:compile && bin/magento cache:flush. - Przetestuj czas odpowiedzi strony przy użyciu narzędzia
curlz pomiarem czasu:curl -s -w 'Time: %{time_total}s\n' -o /dev/null https://twojadomena.pl/kategoria-testowa.
W SISL rekomendujemy regularne czyszczenie kodu z wtyczek, z których sklep realnie nie korzysta. Moduły wyłączone w panelu administracyjnym, ale aktywne w app/etc/config.php, wciąż ładują swoje interceptory do kontenera DI.
Jak sprawdzić konfigurację OpenSearch, Redis i PHP-FPM?
Od wersji 2.4 silnik wyszukiwania nie jest opcjonalny — Magento nie uruchomi się bez OpenSearch (lub Elasticsearch 7.x). Źle dobrana alokacja pamięci dla OpenSearch 2.x powoduje gwałtowny spadek responsywności modułu autosugestii i filtrów fasetowych.
Zweryfikuj te trzy punkty w konfiguracji infrastruktury:
- OpenSearch JVM Heap Size: Pamięć sterty (heap) w pliku
jvm.optionsnie powinna przekraczać 50% całkowitej pamięci RAM maszyny i nie więcej niż 31 GB (ze względu na Compressed OOPs). Dla małego sklepu z katalogiem 20 000 SKU wystarczą 2 GB dedykowanego RAM-u. - Redis - podział na instancje: Nigdy nie używaj jednej bazy Redis dla Cache i Session. Jeśli operacje na sesjach użytkowników trafiają do tej samej instancji co Full Page Cache, duże czyszczenie cache zablokuje wątek pojedynczy (single-threaded) Redisa, co wyloguje klientów lub zawiesi finalizację w checkout.
- PHP-FPM
pm.max_children: Zbyt mała liczba procesów potomnych powoduje kolejkowanie zapytań przy chwilowym skoku ruchu (np. po wysyłce newslettera), co objawia się błędem 504 Gateway Time-out na Nginx.
Co z frontendem: Hyvä Themes vs tradycyjna Luma?
Jeśli wskaźniki Google PageSpeed Insights dla urządzeń mobilnych wskazują wynik poniżej 40 punktów, a wskaźnik INP (Interaction to Next Paint) przekracza 500 ms, problemem nie jest wydajność backendu, lecz przestarzały stack frontendowy oparty na RequireJS, Knockout.js i bibliotekach jQuery.
Przejście na nowoczesny frontend — taki jak Hyvä Themes — redukuje wagę pobieranego kodu JavaScript z typowych 4,5 MB do poniżej 150 KB, drastycznie zmniejszając czas blokowania głównego wątku przeglądarki (TBT). Zanim jednak podejmiesz decyzję o przepisaniu szablonu (co kosztuje od 25 000 do 80 000 PLN w zależności od liczby niestandardowych modułów), upewnij się, że wdrożono podstawowe optymalizacje Lumy: bundling balerem lub zaawansowane scalanie JS, usunięcie zbędnych tagów z GTM oraz serwowanie obrazów w formacie WebP.
Podsumowanie: kiedy checklist to za mało i potrzebujesz wsparcia?
Jeśli po wykonaniu powyższych kroków:
- Varnish poprawnie zwraca nagłówek
HIT, - Indeksy działają w trybie Schedule, a crony nie zgłaszają błędów
Error: Process timed out, - Tabela
cron_schedulei bazy sesyjne Redisa są oczyszczone, - Wykluczono blokady bazy z integracji ERP (Optima, Subiekt, Allegro),
a sklep nadal generuje opóźnienia przy dodawaniu do koszyka lub pod obciążeniem powyżej 50 jednoczesnych użytkowników — problem leży głębiej. W grę wchodzą nieefektywne zapytania SQL w customowych modułach, wycieki pamięci w demonach asynchronicznych lub błędy architektury serwerowej.
W takim wypadku samodzielne testy metodą prób i błędów zabierają zbyt wiele roboczogodzin — napisz do nas, a przeanalizujemy logi, wskażemy dokładne wąskie gardła i wycenimy niezbędne poprawki na podstawie surowych danych telemetrycznych.