停用 WP-Cron(wp-cron.php)常被當成 WordPress 加速的標準動作,但真正該做的不是把它關掉,而是把原本跟著訪客請求跑的排程,交給伺服器在固定時間執行。少了這一步,排程文章、備份、WooCommerce 背景工作或寄信佇列,都可能悄悄停住。
這篇用站長看得懂的方式整理:什麼情況值得改、wp-config.php 要放哪一行、如何用系統 Cron 接手,並附上一份可直接改路徑使用的 shell 腳本。
正確做法不是「關掉 wp-cron.php」,而是「停用前台觸發,改由伺服器穩定觸發」。只做前半段,網站可能暫時變快,後台工作卻開始漏跑。
WP-Cron 是什麼?為什麼會影響 WordPress 效能?
WP-Cron 是 WordPress 內建的排程機制,負責處理預約發文、更新檢查、外掛背景任務、備份、寄信佇列與清理工作。它不是真正由作業系統時鐘喚醒的 Cron,而是網站請求進來時檢查是否有到期工作;需要執行時,再對 wp-cron.php 發出 loopback request。
這個設計很方便,因為一般共享主機不用設定就能運作。但流量變大時,排程檢查會落在使用者請求路徑上;流量很低時,原本該準時跑的任務又可能因為沒人進站而延後。WordPress 近版已把 Cron 的觸發時點移到 shutdown,降低直接影響回應的機會,但官方仍建議在真的有需要時,使用替代方式觸發排程。
哪些網站適合停用 WP-Cron?先看這張判斷表
| 情境 | 建議 | 原因 |
|---|---|---|
| 有 VPS、cPanel 或主機排程功能 | 適合改系統 Cron | 能固定執行、讓前台請求不必兼任排程觸發。 |
| WooCommerce、會員制、定期寄信或排程備份 | 很建議改系統 Cron | 背景工作準時性比等訪客進站可靠。 |
| 流量高、PHP CPU 偶爾飆高 | 先量測後再改 | WP-Cron 可能是原因之一,但慢也可能是外掛、資料庫或登入頁未快取。 |
| 沒有 SSH、主機控制台也沒有 Cron 功能 | 先不要停用 | 沒有替代觸發器時,停用後排程工作會卡住。 |
| 只有簡單形象網站、沒有重要排程 | 不一定需要改 | 官方也說 WP-Cron 已為效能設計,沒有明確問題不必為了設定而設定。 |
如果你的目標是找出網站到底慢在哪裡,不要只猜 WP-Cron。可以先搭配WP-CLI 做 WordPress 效能測試與 WP-Cron 排查,把外掛、資料庫與背景工作一起看;登入狀態變慢的站台,也可以接著檢查WordPress 登入狀態效能調校。
停用前的 4 個檢查:不要先改 wp-config.php
- 確認你有系統排程權限:SSH 的
crontab、cPanel Cron Jobs、Plesk 排程或主機商代設都可以。 - 盤點重要背景工作:預約文章、WooCommerce Action Scheduler、備份外掛、SMTP 寄信、快取預載與同步任務。
- 確認 PHP 可執行:登入主機後跑
command -v php,記下完整路徑,不要假設每台主機都是/usr/bin/php。 - 先用手動方式跑一次:在新增 cron 前先執行腳本,確認路徑與權限沒有問題。
DISABLE_WP_CRON 的作用是停止 WordPress 在一般請求中自動觸發 Cron,不是替你建立伺服器排程。所以請先把替代排程準備好,再寫入停用設定。
Step 1:在 wp-config.php 停用前台觸發
打開 WordPress 根目錄的 wp-config.php,在 /* That's all, stop editing! Happy publishing. */ 這行註解前面加入:
/** 改由伺服器 Cron 定時觸發 WordPress 排程。 */
define( 'DISABLE_WP_CRON', true );
先不要急著存檔上線。若下一步的系統 Cron 還沒設好,這行一生效,網站原本仰賴 WP-Cron 的工作就不會再由前台請求帶起來。
Step 2:用簡單 shell 腳本執行 wp-cron.php
Linux VPS、Cloud VM 或可 SSH 的主機,我會優先使用 PHP 直接執行 wp-cron.php。它不需要對外繞一圈 HTTP,也比較不會被 WAF、Basic Auth 或 Cloudflare 規則擋住。以下腳本加了路徑檢查、避免重複執行的 lock,以及 55 秒 timeout;先把 WP_ROOT 和 PHP_BIN 改成你的環境。
#!/usr/bin/env bash
set -Eeuo pipefail
# 只需改這兩個值。
WP_ROOT="/home/wwwroot/example.com"
PHP_BIN="/usr/bin/php"
LOG_DIR="$HOME/logs"
LOG_FILE="$LOG_DIR/wordpress-cron-example.log"
LOCK_FILE="/tmp/wp-cron-example-com.lock"
if [[ ! -f "$WP_ROOT/wp-cron.php" ]]; then
echo "找不到 $WP_ROOT/wp-cron.php" >&2
exit 1
fi
if [[ ! -x "$PHP_BIN" ]]; then
echo "PHP 執行檔不可用:$PHP_BIN" >&2
exit 1
fi
if ! command -v flock >/dev/null 2>&1; then
echo "找不到 flock,請改用主機提供的防重複機制。" >&2
exit 1
fi
mkdir -p "$LOG_DIR"
exec 9>"$LOCK_FILE"
# 上一輪尚未完成就跳過,避免背景工作同時重複跑。
if ! flock -n 9; then
exit 0
fi
if command -v timeout >/dev/null 2>&1; then
timeout 55s "$PHP_BIN" "$WP_ROOT/wp-cron.php" >> "$LOG_FILE" 2>&1
else
"$PHP_BIN" "$WP_ROOT/wp-cron.php" >> "$LOG_FILE" 2>&1
fi
把它存成 /usr/local/bin/run-wordpress-cron.sh 後,給執行權限並先手動跑一次:
chmod 750 /usr/local/bin/run-wordpress-cron.sh
/usr/local/bin/run-wordpress-cron.sh
執行腳本的 Linux 使用者,必須能讀取 WordPress 目錄,也要有 $HOME/logs 的寫入權限。這也是為什麼我沒有把 log 寫死在 /var/log:一般網站帳號通常沒有那裡的權限。
Step 3:設定 crontab,每 5 分鐘交給系統跑一次
先用網站檔案擁有者登入 SSH,輸入 crontab -e,加入這一行:
*/5 * * * * /usr/local/bin/run-wordpress-cron.sh >/dev/null 2>&1
*/5 代表每 5 分鐘一次。多數企業官網、內容站與一般電商先用這個間隔就夠;若你有付款續約、即時寄信、自動化工作等對時間較敏感的任務,才依需求縮短。反過來說,備份本身很重,不能因為 Cron 很準時就把備份頻率調得太激進。
儲存後,用 crontab -l 確認排程真的存在。再等一個週期,檢查 $HOME/logs/wordpress-cron-example.log 是否有錯誤。若主機商只給 cPanel,概念相同:把腳本命令填到 Cron Jobs,執行週期設定為每 5 或 10 分鐘。
沒有 SSH 時,可以用 HTTP Cron 嗎?可以,但當備案
某些共享主機只有網頁式排程器,無法執行 PHP。這時可以用 HTTP 請求觸發:
curl --fail --silent --show-error --max-time 55 \
--output /dev/null \
"https://example.com/wp-cron.php?doing_wp_cron"
把 example.com 換成自己的網域即可。這種方式符合 WordPress 官方的替代排程方向,但比本機 PHP 多一層 DNS、TLS、WAF 與快取設定。若你使用 Cloudflare 或後台有 IP 限制,HTTP Cron 失敗時不一定會在 WordPress 直接顯示原因,因此能用 PHP 直接跑時,我還是優先選 PHP。
如何確認停用後沒有漏跑?
- 看腳本 exit code 與 log:手動跑一次後,確認沒有找不到檔案、Permission denied 或 PHP fatal error。
- 看 WordPress 網站健康度:後台「工具 → 網站健康度」沒有持續出現逾期背景工作。
- 看 WooCommerce / Action Scheduler:有電商或訂閱功能時,到「工具 → 排程動作」確認沒有大量 overdue 或 failed。
- 做一次可觀察的測試:建立一篇幾分鐘後發布的測試文章,或執行低風險的測試任務,確認時間到了真的會被處理。
- 有 WP-CLI 的主機可再盤點:
wp --path=/你的/WordPress/路徑 cron event list可協助查看目前事件與下一次執行時間。
如果改完後排程文章不發、寄信不送、備份沒跑,先不要一直重裝外掛。第一件事是暫時移除 DISABLE_WP_CRON 或改為 false,讓原本的前台觸發先恢復,再回頭檢查腳本的 WordPress 路徑、PHP 路徑、cron 執行使用者與 log。
常見問題 FAQ
停用 WP-Cron 會讓預約文章不發布嗎?
如果只設定 DISABLE_WP_CRON、卻沒有替代的系統 Cron,會。正確做法是先確認伺服器排程能執行 wp-cron.php,再停用由訪客請求觸發的機制;系統 Cron 正常時,預約文章反而更容易準時發布。
每幾分鐘跑一次系統 Cron 比較好?
多數內容站與一般企業網站可先從每 5 分鐘開始。要依任務需求調整,而不是一律每分鐘:付款、訂閱與即時寄信可能需要較短間隔;備份、清理、報表等重工作則要看伺服器資源與外掛排程。
沒有 SSH 權限也能停用 WP-Cron 嗎?
只有在主機控制台提供 Cron Jobs 或主機商願意代設時才建議停用。若沒有任何替代排程能力,就保留原本 WP-Cron,否則背景工作會因為沒有觸發器而延遲或完全不執行。
停用 WP-Cron 一定會讓網站變快嗎?
不一定。它能把排程觸發移出一般訪客請求,對高流量或背景工作較多的網站很有幫助;但 TTFB、CPU 或後台慢也可能來自慢外掛、資料庫查詢、未快取登入頁或主機資源,應先量測再判斷。
可以用 curl 呼叫 wp-cron.php 嗎?
可以,尤其是共享主機的排程介面只能執行 URL 時。但 HTTP 方式可能受到 DNS、TLS、WAF 或 Cloudflare 影響;有 SSH 且能使用 PHP 時,直接在本機執行 wp-cron.php 通常更單純可靠。
結論:不是關掉排程,而是把排程交給對的地方
WP-Cron 對剛起步的 WordPress 很方便,不需要一開始就把它當成效能敵人。但當網站開始有穩定流量、電商、會員、寄信與備份任務時,讓訪客請求兼任排程觸發就不再是最理想的架構。
最穩的流程是:先建立並手動驗證系統 Cron,確認 log 與排程工作正常,再加入 DISABLE_WP_CRON。這樣前台頁面少一個不必要的工作,背景任務也不必等待下一位訪客來幫你按開關。














