WP-Cron (wp-cron.php): wyłączanie i konfiguracja crona systemowego | Optymalizacja wydajności WordPress

W WordPress zadania cron to funkcja, która automatycznie wykonuje zadania zaplanowane na określoną godzinę lub datę. Działają przez plik wp-cron.php, a WordPress wywołuje ten plik przy każdym wczytaniu strony, by przetworzyć zaplanowane zadania. To proste rozwiązanie, ale na witrynach z dużym ruchem może obniżać wydajność.
Ⅰ. Jak działa WP-Cron i jego problemy z wydajnością
Zamiast tradycyjnego systemu cron na serwerach Linux WordPress ma własną funkcję cron – WP-Cron. WP-Cron działa przez plik wp-cron.php: ⓐ przy każdej wizycie użytkownika sprawdza, czy są zaplanowane zadania, i je wykonuje, a ⓑ wtyczki takie jak Rank Math i WP Rocket uruchamiają własne zaplanowane zadania okresowe.
Z kolei na witrynach z dużym ruchem wp-cron.php może być wywoływany zbyt często, przeciążając serwer. Zwłaszcza gdy wielu użytkowników łączy się naraz, uruchamiają się zduplikowane zadania cron, co może prowadzić do wyższego użycia CPU, wolniejszych odpowiedzi, wolniejszego ładowania stron i podobnych problemów.
Te strukturalne ograniczenia WP-Cron mogą obniżać wydajność WordPressa, a zwłaszcza na witrynach wymagających wysokiej wydajności, w sklepach internetowych i portalach informacyjnych mogą powodować poważne wąskie gardła.
🔄 Jak działa i jak jest zbudowany WP-Cron
Ⅱ. Optymalizacja wydajności WordPress
Wydajność WordPressa można optymalizować na wiele sposobów. Po optymalizacji cache, front-endu i bazy danych można jeszcze poprawić działanie przez ustawienia WP-Cron.
Przy każdym wczytaniu strony WordPress sprawdza zaplanowane zdarzenia, a przez okresowe zadania wtyczek trzeba korzystać z nieefektywnego WP-Cron efektywniej.
1️⃣ Test WP-Cron
Sprawdzając zadania cron w WP-CLI, widać działające zdarzenia cron. Widać, jak wtyczki takie jak Rank Math i WP Rocket uruchamiają zaplanowane zadania codziennie lub co kilka minut.

2️⃣ Jak skonfigurować WP-Cron
WP-Cron to wirtualny harmonogram obsługujący zaplanowane zadania WordPressa; wp-cron.php uruchamia się przy wizytach użytkowników. Jednak wykonywanie zależne od ruchu jest zawodne, a nadmiar wywołań może obciążać serwer, więc zwykle uzupełnia się go cronem systemowym.
W razie potrzeby zaleca się ustawić DISABLE_WP_CRON w wp-config.php, wyłączyć WP-Cron i uruchamiać go regularnie cronem Linuksa.
|
Pozycja |
Wyłączenie WP-Cron + tylko cron systemowy |
|---|---|
|
Ustawienia |
Wyłączyć WP-Cron i uruchamiać wp-cron.php z crona systemowego |
|
Zalety |
Brak zduplikowanych uruchomień, dokładne wykonanie o czasie i małe obciążenie serwera |
|
Wady |
Niektóre funkcje wtyczek mogą przestać działać, a błąd konfiguracji grozi pominięciem zadań |
|
Zalecane · Sytuacja |
Dla witryn z dużym ruchem i wieloma zaplanowanymi zadaniami |
Metoda ① ma jednak wadę: wyłącza funkcję preload wtyczek cache takich jak WP Rocket, która co minutę buduje cache z wyprzedzeniem, zanim przyjdą odwiedzający.
⚙️ Edycja pliku wp-config.php
Możesz to ustawić, wyłączając WP_CRON.
# Wyłącz WP_CRON
define( 'DISABLE_WP_CRON', true );Gdy WP-Cron działa, WP_CRON_LOCK_TIMEOUT pełni rolę [blokady czasowej], która powstrzymuje inne próby uruchomienia.
# 5 minut = 300, co 60 minut = 3600
define('WP_CRON_LOCK_TIMEOUT', 300);Dlatego zamiast tylko wyłączać WP-Cron w pliku wp-config.php, zalecam wyłączyć go, a potem dodać zadanie System Cron ; serwer, którym teraz zarządzam, też jest tak skonfigurowany.
⚙️ Włączenie crona systemowego na serwerze Linux [podstawy]
Możesz go włączyć dla każdej domeny osobno.
# Uruchamiaj co 5 minut
*/5 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
# Uruchamiaj co 30 minut
*/30 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
# Uruchamiaj co godzinę
0 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
# Uruchamiaj raz dziennie
0 3 * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1Cztery powyższe wiersze to przykłady dla różnych odstępów dodawane do crontab; o każdej ustalonej porze curl wywołuje adres [wp-cron.php], więc zaplanowane zadania działają nawet bez odwiedzających.
# Jeśli serwer jest lokalny
*/5 * * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1
# Uruchamiaj co 30 minut
*/30 * * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1
# Uruchamiaj co godzinę
0 * * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1
# Uruchamiaj raz dziennie
0 3 * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1Jeśli masz WP-CLI, możesz ustawić jeden wiersz dla wybranego odstępu. ▼
# Uruchamiaj co 5 minut
*/5 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet
# Uruchamiaj co 30 minut
*/30 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet
# Uruchamiaj co godzinę
0 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet
# Uruchamiaj raz dziennie
0 3 * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quietW tej konfiguracji WP-CLI uruchamia na serwerze tylko zaległe zaplanowane zadania z opcją [--due-now], a [flock -n] pomija nowe uruchomienie, jeśli poprzednie się nie skończyło.
⚙️ WP-CLI i cron systemowy co minutę oraz ochrona przed duplikacją zadań cron
Domyślnie WP_CRON przy dużej liczbie zadań po prostu je ignoruje (pomija) i uruchamia później. Wyłącz domyślny WP-Cron i ustaw dla zaplanowanych zadań 5-minutową blokadę, by cron systemowy i WP-Cron nie działały jednocześnie.
define('DISABLE_WP_CRON', true); // wyłącza automatyczne uruchamianie WP-Cron
define('WP_CRON_LOCK_TIMEOUT', 300); // bez czekania → pominięte; utrzymuje 5-minutową blokadę podczas zaplanowanego zadania
/* That's all, stop editing! Happy publishing. */Dodaj opcję flock -n do crona systemowego, aby po stronie crona uruchomienie, które zastanie blokadę, kończyło się od razu.
# ustawienie wp cron: flock -n → bez czekania → natychmiastowe wyjście
*/1 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quietWynik takiego połączenia ustawień:
- Wewnętrzne automatyczne uruchamianie WP jest wyłączone → zaplanowane zadania działają niezależnie od liczby odwiedzających
- Cron systemowy próbuje uruchamiać co minutę → zaplanowane zadania wykonują się, jeśli są
- Po zablokowaniu przez 5 minut nic nie uruchamia się ponownie → zapobiega duplikacji (w praktyce przy flock -n WP_CRON_LOCK_TIMEOUT nie jest właściwie potrzebny.)
Przy ochronie przed duplikacją rzeczywisty przebieg wygląda tak:
- 08:00 → cron systemowy wywołuje wp-cron.php
- Zadanie A się wykonuje → blokada na 5 minut
- 08:01 → cron systemowy wywołuje ponownie
- Zadanie A zablokowane → nie wykonuje się
- 08:02–08:04 → tak samo
- 08:05 → blokada zwolniona → następne zaplanowane zadanie się wykona, jeśli jest
Zamiast WordPressa zadania automatycznie uruchamia system i to on za nie odpowiada. A WP_CRON_LOCK_TIMEOUT działa jako dodatkowe zabezpieczenie przed duplikacją.
|
Pozycja |
WP_CRON_LOCK_TIMEOUT |
flock -n |
|---|---|---|
|
Rodzaj blokady |
Wewnątrz WordPressa |
Poziom systemu |
|
Miejsce blokady |
W bazie danych: doing_cron w wp_options |
W pliku systemowym: ~/.wp_cron.lock |
|
Czeka? |
❌ Nie czeka → pomija |
❌ Nie czeka → kończy od razu |
|
Ochrona przed duplikacją |
✅ Zapobiega duplikacji |
✅ Zapobiega duplikacji |
Na koniec możesz sprawdzić poleceniem WP-CLI, czy cron działa jak wcześniej.
wp cron event list+-------------------------------------------+---------------------+-----------------------+---------------+
| hook | next_run_gmt | next_run_relative | recurrence |
+-------------------------------------------+---------------------+-----------------------+---------------+
| rocket_saas_pending_jobs | 2026-10-17 12:00:57 | now | 1 minute |
| action_scheduler_run_queue | 2026-10-17 12:00:57 | now | 1 minute |
| action_scheduler_run_queue_rucss | 2026-10-17 12:00:58 | now | 1 minute |
| rocket_saas_on_submit_jobs | 2026-10-17 12:00:58 | now | 1 minute |
| rocket_preload_process_pending | 2026-10-17 12:00:59 | now | 1 minute |
| rocket_purge_time_event | 2026-10-17 12:16:59 | 15 minutes 8 seconds | 1 hour |
| wp_privacy_delete_old_export_files | 2026-10-17 12:28:46 | 26 minutes 55 seconds | 1 hour |
| wp_update_user_counts | 2026-10-17 20:15:52 | 8 hours 14 minutes | 12 hours |
| rocket_preload_revert_old_failed_rows | 2026-10-17 20:17:59 | 8 hours 16 minutes | 12 hours |
| wp_version_check | 2026-10-17 20:28:34 | 8 hours 26 minutes | 12 hours |
| wp_update_plugins | 2026-10-17 20:58:34 | 8 hours 56 minutes | 12 hours |
| wp_update_themes | 2026-10-17 21:28:34 | 9 hours 26 minutes | 12 hours |
| recovery_mode_clean_expired_keys | 2026-10-18 07:28:46 | 19 hours 26 minutes | 1 day |
| wp_privacy_personal_data_cleanup_requests | 2026-10-18 07:28:46 | 19 hours 26 minutes | 1 day |
| wp_scheduled_delete | 2026-10-18 08:15:52 | 20 hours 14 minutes | 1 day |
| delete_expired_transients | 2026-10-18 08:15:52 | 20 hours 14 minutes | 1 day |
| wp_scheduled_auto_draft_delete | 2026-10-18 08:15:54 | 20 hours 14 minutes | 1 day |
| wp_delete_temp_updater_backups | 2026-10-18 08:16:17 | 20 hours 14 minutes | 1 week |
| rocket_update_dynamic_lists | 2026-10-18 08:16:57 | 20 hours 15 minutes | 1 week |
| rocket_saas_clean_rows_time_event | 2026-10-18 08:16:57 | 20 hours 15 minutes | 1 week |
| rocket_performance_hints_cleanup | 2026-10-18 08:16:58 | 20 hours 15 minutes | 1 day |
| rocket_preload_clean_rows_time_event | 2026-10-18 08:26:57 | 20 hours 25 minutes | 1 week |
| rocket_database_optimization_time_event | 2026-10-18 09:34:25 | 21 hours 32 minutes | 1 day |
| wp_site_health_scheduled_check | 2026-10-19 07:28:46 | 1 day 19 hours | 1 week |
| rocket_remove_saas_failed_jobs | 2026-10-19 08:16:58 | 1 day 20 hours | 3 days |
+-------------------------------------------+---------------------+-----------------------+---------------+Wynik pokazuje nazwy zarejestrowanych hooków, czas następnego uruchomienia i powtarzalność, a zadania z [now] w kolumnie [next_run_relative] zostaną przetworzone od razu przy następnym uruchomieniu crona.
Ⅲ. Gdy zaplanowane zadania WP-Cron nie działają
Łatwo założyć, że zadanie uruchomi się samo o zaplanowanej porze, ale WP-Cron sprawdza, co jest do zrobienia, gdy przychodzi żądanie strony, a nie o ustalonej godzinie. Zadanie zaplanowane na 14:00 wykona się przy pierwszym żądaniu o 17:00, jeśli wcześniej żadne nie przyjdzie.
Gdy uruchomienia się opóźniają, zaplanowane wpisy na liście wpisów mają status [Pominięto harmonogram]. W [Zalecane ulepszenia] na karcie Stan w [Narzędzia › Stan witryny] pojawia się [Zaplanowane zdarzenie nie powiodło się]. Zadania zarejestrowane przez wtyczki, np. wstępne ładowanie cache, czekają z tego samego powodu.
Zaplanowane zadania wykonują się w [wp-cron.php] po żądaniu strony, sprawdzeniu zadań i żądaniu loopback; jeśli któreś ogniwo zawiedzie, nie wykonają się nawet po czasie.
1️⃣ Gdy nie ma wizyt lub odpowiada cache stron
WP-Cron sprawdza zadania tylko przy żądaniach uruchamiających WordPressa, więc w godzinach bez wizyt zadania po czasie po prostu się kumulują. Nawet przy wizytach wynik jest ten sam, gdy odpowiada plik cache strony, bo WordPress się nie uruchamia.
Na WordPressie z włączonym cache stron WP Rocket otwarcie zbuforowanej strony głównej nie zapisało wywołania [wp-cron.php]. Otwarcie niezbuforowanego adresu zapisało wywołanie w tej samej sekundzie i pięć zaległych zadań się wykonało.
Zaległe zadania sprawdzisz, filtrując listę WP-CLI do wierszy, w których [next_run_relative] to [now].
wp cron event list --next_run_relative=now --fields=hook,next_run_gmt,next_run_relative+----------------------------------+---------------------+-------------------+
| hook | next_run_gmt | next_run_relative |
+----------------------------------+---------------------+-------------------+
| rocket_saas_pending_jobs | 2026-10-17 14:49:57 | now |
| action_scheduler_run_queue | 2026-10-17 14:49:57 | now |
| action_scheduler_run_queue_rucss | 2026-10-17 14:49:58 | now |
| rocket_saas_on_submit_jobs | 2026-10-17 14:49:58 | now |
| rocket_preload_process_pending | 2026-10-17 14:49:59 | now |
+----------------------------------+---------------------+-------------------+[now] oznacza, że zaplanowany czas już minął. To polecenie listy też wczytuje WordPressa, więc jeśli są zaległe zadania, wywołuje [wp-cron.php] zaraz po zakończeniu. Gdy od razu uruchomisz to samo polecenie, zadania, które przed chwilą widziałeś, znikną z listy.
Aby nadrobić zaległe zadania przed usunięciem przyczyny, uruchom od razu w WP-CLI tylko zadania po terminie.
wp cron event run --due-nowExecuted the cron event 'rocket_saas_pending_jobs' in 0.005s.
Executed the cron event 'action_scheduler_run_queue' in 0.006s.
Executed the cron event 'action_scheduler_run_queue_rucss' in 0.006s.
Executed the cron event 'rocket_saas_on_submit_jobs' in 0.005s.
Executed the cron event 'rocket_preload_process_pending' in 0.007s.
Success: Executed a total of 5 cron events.To polecenie wykonuje zadania na serwerze bez żądania HTTP; aby przetwarzać je w stałych odstępach niezależnie od wizyt, dodaj to samo polecenie do crona systemowego.
2️⃣ Gdy włączone jest tylko DISABLE_WP_CRON i nie ma crona systemowego
Przy [DISABLE_WP_CRON] ustawionym na true WP-Cron nie sprawdza zadań nawet przy żądaniach stron. Oficjalna dokumentacja też każe najpierw zarejestrować zadanie w systemowym harmonogramie, a potem dodać tę stałą; sama stała bez rejestracji sprawia, że nie ma nic, co wykona zaplanowane zadania.
Przy włączonej stałej wpis zaplanowany na nieco ponad minutę później pozostał po czasie jako [Zaplanowany], a w kolumnie daty listy wpisów pojawiło się [Pominięto harmonogram]. W tym czasie nie zapisano ani jednego wywołania [wp-cron.php].
Czy stała jest włączona, sprawdzisz poleceniem [wp cron test].
wp cron testError: The DISABLE_WP_CRON constant is set to true. WP-Cron spawning is disabled.Jeśli pojawi się ten błąd, sprawdź, czy cron systemowy ma wiersz wywołujący [wp-cron.php] lub uruchamiający [wp cron event run]. Gdy crontab konta witryny jest pusty, zobaczysz to:
crontab -lno crontab for exampleJeśli takiego wiersza nie ma, dodaj cron systemowy; jeśli środowisko na to nie pozwala, usuń wiersz [DISABLE_WP_CRON] i znów korzystaj z WP-Cron.
3️⃣ Gdy żądanie loopback serwera jest zablokowane
Gdy jest co robić, WP-Cron każe serwerowi wysłać żądanie do [wp-cron.php] pod własnym adresem witryny, by wykonać zadania; to żądanie loopback. Jeśli reguła bezpieczeństwa blokuje [wp-cron.php], żądanie loopback wraca z 403, a zadania się nie wykonują.
Na serwerze z Nginx i Apache ograniczenie [wp-cron.php] tylko do 127.0.0.1 zablokowało żądanie loopback błędem 403. Dzieje się tak, bo żądanie, które serwer wysyła do własnej domeny, przychodzi przez publiczny adres IP, a [wp cron test] zwraca ten sam kod stanu.
wp cron testError: WP-Cron spawn returned HTTP status code: 403 ForbiddenPrzy zadaniach opóźnionych o ponad pięć minut ekran [Stan witryny] pokazał w [Zalecane ulepszenia] jednocześnie ostrzeżenie o loopback i nieudane zaplanowane zdarzenie.

Po usunięciu reguły [wp cron test] znów się powiódł. Jeśli regułę trzeba zachować, uruchamiaj zadania przez WP-CLI z crona systemowego. Uruchomienie WP-CLI nie przechodzi przez żądanie HTTP, więc zaległe zadania przetworzyły się nawet przy tej samej regule.
🔢 FAQ & polecane treści





ℹ️ Informacja o linkach partnerskich
Treści tej witryny zawierają linki partnerskie. Jeśli odwiedzający kupi produkt lub usługę przez taki link, witryna otrzymuje od sprzedawcy prowizję. Kwota płacona przy tym przez kupującego (podczas promocji spada↓) nie wzrasta. Podane ceny, rabaty i dostępność odnoszą się do chwili pisania i mogą różnić się od stanu faktycznego, dlatego przed zakupem sprawdź je u sprzedawcy. Produkty wybieramy i oceniamy według własnych kryteriów, a prowizja nie wpływa ani na kolejność prezentacji, ani na treść ocen.