WP-Cron(wp-cron.php):停用與設定系統 Cron | WordPress 效能最佳化

WordPress 的 Cron 排程工作是在特定時間或日期自動執行排定工作的功能。這些工作透過 wp-cron.php 檔案執行,WordPress 每次載入頁面時都會呼叫這個檔案,處理排定的工作。這種方式雖然簡便,但在流量大的網站上可能會降低效能。
Ⅰ. WP-Cron 的執行過程與效能問題
WordPress 不使用 Linux 伺服器傳統的 Cron 系統,而是提供自己的 Cron 功能 WP-Cron。WP-Cron 透過 wp-cron.php 檔案運作:ⓐ 每當使用者造訪網站時,檢查有沒有排程工作並加以執行;ⓑ Rank Math、WP Rocket 等外掛則會自行執行排定的週期性工作。
反過來說,在流量大的網站上,wp-cron.php 可能被過於頻繁地呼叫,造成伺服器負載過重。特別是多位使用者同時連線時,會執行重複的 Cron 工作,進而導致 CPU 使用率上升, 回應延遲, 頁面載入速度變慢 等問題。
WP-Cron 這種結構上的限制可能拖慢 WordPress 的效能,特別是在 需要高效能的網站、購物網站、新聞入口網站 等地方,可能造成嚴重的效能瓶頸。
🔄 WP-Cron 的執行方式與結構
Ⅱ. WordPress 效能最佳化
WordPress 效能最佳化的方法有很多種。在完成快取、前端與資料庫等最佳化之後,還可以透過 WP-Cron 的設定進一步改善。
每次載入 WordPress 頁面都會檢查排程事件,再加上外掛的週期性工作,需要更有效率地運用效率不佳的 WP-Cron。
1️⃣ 測試 WP-Cron
用 WP-CLI 檢查 Cron 工作時,可以看到正在運作的 Cron 被執行。也能確認 Rank Math、WP Rocket 等外掛以每天或每幾分鐘的間隔執行排程工作。

2️⃣ WP-Cron 設定方法
WP-Cron 是處理 WordPress 排程工作的虛擬排程器,使用者造訪時就會執行 wp-cron.php。但以流量為基礎的執行方式並不穩定,過度呼叫也可能造成伺服器負載,所以一般會用系統 Cron 來補足。
必要時,建議在 wp-config.php 設定 DISABLE_WP_CRON 關閉 WP-Cron,再用 Linux 的 Cron 定期執行。
|
項目 |
停用 WP-Cron + 只用系統 Cron 執行 |
|---|---|
|
設定 |
關閉 WP-Cron,由系統 Cron 執行 wp-cron.php |
|
優點 |
沒有重複執行,能依時間準確執行,伺服器負載也低 |
|
缺點 |
部分外掛功能可能中斷,設定出錯時有漏掉工作的風險 |
|
適用的 情況 |
適合流量大、排程工作多的網站 |
不過,第 ① 種方式有個缺點:WP Rocket 這類快取外掛每 1 分鐘透過 PreLoad 功能,在訪客造訪網頁前預先產生快取,這個功能會被停用。
⚙️ 修改 wp-config.php 檔案
可以用停用 WP_CRON 的方式來設定。
# 停用 WP_CRON
define( 'DISABLE_WP_CRON', true );WP-Cron 執行期間,WP_CRON_LOCK_TIMEOUT 是 防止其他執行嘗試的 [時間鎖定機制]。
# 5 分鐘設 300,每 60 分鐘執行設 3600
define('WP_CRON_LOCK_TIMEOUT', 300);基於這些原因,與其只在 wp-config.php 檔案中停用 WP-Cron,更建議停用後再加入 System Cron 工作,目前管理中的伺服器也是這樣設定的。
⚙️ 在 Linux 伺服器啟用系統 Cron [基本]
可以按個別網域啟用。
# 每 5 分鐘執行
*/5 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
# 每 30 分鐘執行
*/30 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
# 每 1 小時執行
0 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
# 每天執行 1 次
0 3 * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1上面四行是加入 crontab 的各週期範例,每到指定時間,curl 就會呼叫 [wp-cron.php] 網址,即使沒有訪客,排程工作也會執行。
# 伺服器為本機伺服器時
*/5 * * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1
# 每 30 分鐘執行
*/30 * * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1
# 每 1 小時執行
0 * * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1
# 每天執行 1 次
0 3 * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1如果已安裝 WP-CLI,只要依想要的間隔設定一行即可。▼
# 每 5 分鐘執行
*/5 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet
# 每 30 分鐘執行
*/30 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet
# 每 1 小時執行
0 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet
# 每天執行 1 次
0 3 * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet這是讓伺服器內的 WP-CLI 以 [--due-now] 選項只執行到期排程工作的設定,[flock -n] 則會在前一次執行尚未結束時跳過新的執行。
⚙️ WP-CLI 與每 1 分鐘的系統 Cron,以及防止 Cron 工作重複執行
原本的 WP_CRON 在工作量多時會直接略過(跳過),之後再重新執行。關閉原本的 WP-Cron,並讓排程工作維持 5 分鐘鎖定,就能避免系統 Cron 與 WP-Cron 重疊執行。
define('DISABLE_WP_CRON', true); // 關閉 WP-Cron 自動執行
define('WP_CRON_LOCK_TIMEOUT', 300); // 不等待 → 略過(跳過);執行排程工作時維持 5 分鐘鎖定
/* That's all, stop editing! Happy publishing. */再為系統 Cron 加上 flock -n 選項,讓系統 Cron 這邊遇到鎖定就立即結束。
# wp cron 設定:flock -n → 不等待 → 立即結束
*/1 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet以上設定組合的結果是:
- WP 內部自動執行已關閉 → 排程工作的執行與訪客人數無關
- 系統 Cron 每 1 分鐘嘗試執行 → 有排程工作就會執行
- 鎖定後 5 分鐘內不會重新執行 → 防止重複執行(實際上有了 flock -n 設定,WP_CRON_LOCK_TIMEOUT 並非必要。)
加上防止重複執行後,實際的運作流程是:
- 08:00 → 系統 Cron 呼叫 wp-cron.php
- 排程工作 A 執行 → 設定 5 分鐘鎖定
- 08:01 → 系統 Cron 再次呼叫
- 工作 A 鎖定中 → 不執行
- 08:02~08:04 → 相同
- 08:05 → 解除鎖定 → 有下一個排程工作就會執行
不是由 WP 自動執行,而是改由系統負責執行。 而 WP_CRON_LOCK_TIMEOUT 則作為防止重複執行的輔助安全機制運作。
|
項目 |
WP_CRON_LOCK_TIMEOUT |
flock -n |
|---|---|---|
|
鎖定方式 |
WordPress 內部 |
系統層級 |
|
鎖定位置 |
以 DB 為基礎:wp_options 的 doing_cron |
以系統檔案為基礎:~/.wp_cron.lock |
|
是否等待 |
❌ 不等待 → 跳過 |
❌ 不等待 → 立即結束 |
|
防止重複執行 |
✅ 防止重複執行 |
✅ 防止重複執行 |
完成後可以用 WP-CLI 指令檢查,確認 Cron 是否像原本一樣正常運作。
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 |
+-------------------------------------------+---------------------+-----------------------+---------------+輸出會顯示已註冊的 hook 名稱、下次執行時間與重複週期,[next_run_relative] 欄為 [now] 的工作會在下一次 Cron 執行時立即處理。
Ⅲ. WP-Cron 排程工作沒有執行時
很容易以為到了排定時間工作就會自動執行,但 WP-Cron 不是看時間,而是在有頁面要求進來時才檢查要做的事。排在下午 2 點的工作,如果到下午 5 點都沒有要求,就會在 5 點的第一個要求時才執行。
執行一旦延後,排程發佈的文章會在文章列表中顯示為 [已錯過排程](Missed schedule)。在 [工具 › 網站狀態] 畫面的狀態分頁中,[建議改進項目] 會出現 [排程事件執行失敗]。像快取預先載入這類由外掛註冊的工作,也會因為同樣的原因等待執行。
排程工作會經過頁面要求、檢查待辦工作、回送要求,最後在 [wp-cron.php] 執行,其中任何一環中斷,時間過了也不會執行。
1️⃣ 沒有造訪或由頁面快取回應時
WP-Cron 只在會執行 WordPress 的要求中檢查待辦工作,所以沒有造訪的時段,已過時間的工作會一直累積。即使有造訪,只要由頁面快取檔案回應,WordPress 就不會執行,結果也一樣。
在開啟 WP Rocket 頁面快取的 WordPress 上,打開已快取的首頁時,沒有記錄到 [wp-cron.php] 呼叫。打開不會被快取的網址後,同一秒就記錄到呼叫,積壓的五個工作也執行了。
積壓的工作可以在 WP-CLI 清單中只篩出 [next_run_relative] 為 [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] 表示預定時間已經過了。這個列表指令也會載入 WordPress,所以有積壓工作時,指令結束的瞬間就會呼叫 [wp-cron.php]。馬上再執行同一個指令,剛才看到的工作就已經從清單中消失。
如果想在修正原因之前先處理積壓的工作,可以用 WP-CLI 只立即執行已到期的工作。
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.這個指令不經 HTTP 要求,直接在伺服器內執行工作;如果想不受造訪影響、按固定間隔處理,就把同一個指令加入系統 Cron。
2️⃣ 只開啟 DISABLE_WP_CRON 卻沒有系統 Cron 時
把 [DISABLE_WP_CRON] 設為 true,即使有頁面要求進來,WP-Cron 也不會檢查待辦工作。官方文件也是指示先在系統的工作排程器設定好,再加入這個常數;沒有設定就只加常數的話,就沒有地方執行排程工作了。
加入常數後,排在 1 分鐘多之後的文章過了時間仍維持 [已排程],文章列表的日期欄則顯示 [已錯過排程]。這段期間一次 [wp-cron.php] 呼叫都沒有被記錄。
可以用 [wp cron test] 確認常數是否開啟。
wp cron testError: The DISABLE_WP_CRON constant is set to true. WP-Cron spawning is disabled.出現這個錯誤時,檢查系統 Cron 裡有沒有呼叫 [wp-cron.php] 或執行 [wp cron event run] 的行。如果網站帳號的 crontab 是空的,會顯示如下。
crontab -lno crontab for example沒有這一行就設定系統 Cron;如果環境無法設定,就刪掉 [DISABLE_WP_CRON] 那一行,重新使用 WP-Cron。
3️⃣ 伺服器的回送要求被擋下時
有待辦工作時,WP-Cron 會讓伺服器向自己網站網址的 [wp-cron.php] 送出要求來執行工作,這個要求就是回送要求。如果有擋下 [wp-cron.php] 的安全規則,回送要求會收到 403,工作就不會執行。
在 Nginx 與 Apache 架構的伺服器上,把 [wp-cron.php] 限制為只能從 127.0.0.1 開啟後,回送要求就被 403 擋下。這是因為伺服器送往自己網域的要求是從公用 IP 進來的,[wp cron test] 也會回傳相同的狀態碼。
wp cron testError: WP-Cron spawn returned HTTP status code: 403 Forbidden在工作積壓超過 5 分鐘的狀態下打開 [網站狀態] 畫面,[建議改進項目] 中同時出現回送要求警告與排程事件失敗。

刪掉規則後,[wp cron test] 又恢復成功。如果必須保留規則,就從系統 Cron 用 WP-CLI 執行。WP-CLI 執行不經過 HTTP 要求,所以在規則仍在的狀態下,積壓的工作也處理掉了。
🔢 FAQ & 推薦內容



ℹ️ 聯盟行銷說明
本站內容包含聯盟行銷連結。訪客透過這些連結購買商品或服務時,本站會從賣家獲得佣金。在這個過程中,購買者支付的金額(遇到活動折扣時金額會降低↓)並不會因此提高。刊登的價格、折扣與庫存資訊以撰寫當時為準,可能與實際情況不同,購買前請向賣家做最後確認。商品的挑選與評價依本站自訂的標準撰寫,是否支付佣金不會影響介紹順序或評價內容。


