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などのプラグインが、予約タスクを1日単位や分単位で実行していることが確認できます。

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_LOCK_TIMEOUTは、WP-Cronの実行中に ほかの実行の試みを防ぐ[時間ベースのロック]です。
# 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日1回実行
0 3 * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1上の4行はcrontabに登録する間隔別の例で、指定した時刻ごとにcurlが[wp-cron.php]のURLを呼び出すため、訪問者がいなくても予約タスクが実行されます。
# サーバーがローカルサーバーの場合
*/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日1回実行
0 3 * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1WP-CLIをインストールしている場合は、希望する間隔で1つだけ設定できます。▼
# 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日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とシステムcron(1分)、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 |
+-------------------------------------------+---------------------+-----------------------+---------------+出力には登録されたフック名と次回の実行時刻、繰り返し間隔が表示され、[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]の呼び出しが記録されませんでした。キャッシュされないURLを開くと同じ秒に呼び出しが記録され、溜まっていたタスク5つが実行されました。
溜まったタスクは、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 & おすすめコンテンツ






ℹ️ 提携について
当サイトのコンテンツにはアフィリエイトリンクが含まれています。訪問者がこのリンクを通じて商品やサービスを購入すると、当サイトは販売元から手数料を受け取ります。この過程において、購入者が支払う金額(イベント割引適用で金額が下がります↓)は上昇しません。掲載されている価格・割引・在庫情報は作成時点のものであり、実際とは異なる場合がありますので、ご購入前に販売元にて最終確認をお願いいたします。商品の選定および評価は独自の基準に基づいて行われており、手数料の支払いの有無は紹介順や評価内容に影響を与えません。