予約投稿が「予約済み」のまま出ない、バックアップやメール配信が予定時刻より遅い。こうした時に原因候補になるのがWP-Cronです。WordPress公式は、WP-Cronがページロードのたびに実行待ちタスクを確認し、アクセスがなければ予定時刻を過ぎる可能性があると説明しています。
WP-Cronとsystem cronの違い
| 項目 | WP-Cron | system cron |
|---|---|---|
| 起動 | ページアクセスがきっかけ | OS/ホスティングの時刻指定 |
| 低アクセス | 遅れる可能性 | 指定間隔で起動 |
| 設定難易度 | WordPress標準 | サーバー設定が必要 |
| 共有サーバー | そのまま使いやすい | 提供機能に依存 |
| 向く用途 | 一般ブログ・軽い定期処理 | 時刻精度が必要な処理 |
WP-Cronで動いている代表的な処理
- 予約投稿の公開
- WordPress本体・テーマ・プラグインの更新確認
- 一部バックアッププラグインの定期実行
- メールキューや通知
- 期限切れデータや一時データの整理
- 外部APIからの同期
つまりWP-Cronを止めると、目に見える予約投稿だけでなく裏側の保守処理も止まる可能性があります。「自分は予約投稿を使わないから無効化してよい」とは限りません。
WP-Cronが原因かを確認する
予約投稿だけ遅れる
アクセスが少ない時間帯に予約した記事が遅れるなら、WP-Cronの仕組みと整合します。ただしタイムゾーン、予約日時、プラグイン競合も確認します。
Site HealthやWP-CLIでテストする
WP-CLIが使える環境ではwp cron test、wp cron event listなどでイベントを確認できます。大量に同じイベントが重複している場合、プラグイン側が毎回再登録していないかも見ます。
セキュリティ設定でloopbackが止まっていないか
WAF、Basic認証、Cloudflare Accessなどを追加すると、wp-cron.phpへのloopbackが意図せず拒否されることがあります。環境を強化した直後にCronが止まったなら、アクセス制御を疑います。
Cronだけでなく、Site Healthのloopback、REST API、Webhookも似た経路の影響を受けることがあります。セキュリティ設定を変えた後は、この4つをまとめて確認すると「Cronだけの問題」と誤認しにくくなります。
Cronの遅延と失敗を分ける
予定時刻を数分過ぎて次のアクセスで動いたなら、WP-Cronの性質による遅延かもしれません。一方、何時間経っても動かない、毎回同じhookが失敗する、loopback errorが出る場合は「遅延」ではなく「実行失敗」と考えます。
system cronへ切り替えても、実行先のwp-cron.php自体が403や500なら直りません。まずWordPress側のCronが正常に起動できる状態を作ってから、時刻精度のために起動方法だけ置き換えます。
「予約投稿の失敗」はこの順に切り分ける
| 症状 | 確認 | 次の一手 |
|---|---|---|
| 数分遅れて公開される | 低アクセス時間帯か | WP-Cronの性質として許容できるか判断 |
| 何時間も公開されない | Site Health / wp cron test | loopback・fatal・WAFを確認 |
| 特定プラグインだけ失敗 | 該当hook / error log | プラグイン由来イベントを切り分け |
| 高負荷時だけ失敗 | 同時Cron・バックアップ | イベント時刻を分散 |
「Missed schedule」表示だけを見てsystem cronへ切り替えるのではなく、起動が遅いのか、起動して処理内部で失敗しているのかを分けることが重要です。
system cronへ切り替える手順の考え方
- 現在のWP-Cronが正常に動いているか確認
- サーバー側cron機能の有無を確認
- wp-cron.phpを5〜15分程度の間隔で呼ぶ設計を検討
- 外部呼び出しが安定したことを確認
DISABLE_WP_CRONをtrueにしてページロード起動を止める- 予約投稿・バックアップ・メールを実運用で確認
system cronや外部定期実行を作る前にWP-Cronを無効化すると、予約投稿や更新確認などの定期処理が止まります。切替は「新しい起動経路を作る→確認→標準起動を止める」の順です。
HTTPでwp-cron.phpを呼ぶか、WP-CLIでdue eventを実行するか
サーバー側cronでは、wp-cron.phpをHTTPで呼ぶ方法と、WP-CLIが使える環境でwp cron event run --due-nowを実行する方法があります。後者はWordPressを直接起動して期限イベントを実行できるため、外部HTTP・DNS・WAFの影響を受けにくい利点があります。ただし共有サーバーではWP-CLIやcronコマンドの利用可否が異なるため、ホストの公式手順を優先してください。
何分間隔で動かすべき?
正解はサイト用途で変わります。一般ブログで予約投稿や軽いメンテナンス中心なら5〜15分間隔でも十分な場合があります。一方、EC・会員サイト・キュー処理では業務要件から決めます。1分間隔にすれば良いわけではなく、処理時間より短い間隔で重複起動すると逆に負荷が増えます。
Cronの負荷を下げる考え方
system cronへ変えるだけでなく、重いイベントの時間帯を分散します。バックアップ、画像最適化、外部同期、サイトマップ生成を同じ深夜0時に集中させると、共有サーバーではピークを自分で作ってしまいます。10分〜数十分ずらすだけでも競合を減らせます。
高アクセスサイトでは「Cronが遅れる」より、外部API・画像処理・バックアップ・大量メールが同時実行される方が問題になることがあります。イベント数ではなく開始・終了時刻と総実行時間を記録し、長い処理や重複する処理をずらします。
実行確認を「時刻」だけにしない
Cronは指定時刻に起動しても、処理内部でAPIエラーやメール失敗が起きれば業務結果は出ません。予約投稿なら公開URL、バックアップなら保存ファイル、メールなら受信、同期なら更新件数まで確認します。「Cronが走った」ではなく「期待した結果ができた」を監視対象にすると見落としを減らせます。
重要処理では、最後に成功した時刻と失敗回数を管理画面やログへ残し、一定時間成功がなければ通知する設計が有効です。
予約投稿が重要なサイトの運用設計
ニュース、キャンペーン、期間限定ページのように「指定時刻に公開されること」自体が価値なら、system cronを検討する理由が強くなります。さらに公開後チェックを自動化し、予定時刻から一定時間経っても公開されなければ通知する仕組みまで作ると、Cronの成功を「設定したはず」ではなく「結果が出た」で確認できます。
プラグイン削除後のCron残骸
WordPress公式は、プラグインが無効化・削除時に自分のイベントをunscheduleする重要性を説明しています。古いイベントが残っていると、存在しない処理を探し続けたり、不要な外部通信を試す可能性があります。使っていないイベントが見つかったら、どのプラグイン由来かを確認してから整理します。
WP-Cronを高速化目的だけで触るべきか
WordPress 6.9では通常のCron spawnコールバックがwp_loadedからshutdownへ移され、HTML送信を待たせにくい改善も入りました。つまり古い記事にある「WP-Cronは必ずTTFBを悪化させる」という単純化は避けるべきです。問題がなければ標準のままでも構いません。
僕なら、予約投稿遅延・Cron失敗・高トラフィックでの重複起動など、具体的な症状がある時だけ切り替えます。
切替後の監視項目
| 確認 | 見るもの | 失敗時 |
|---|---|---|
| 予約投稿 | 予定時刻からの遅れ | Cronログ/時刻設定 |
| バックアップ | 開始・完了時刻 | 処理重複・タイムアウト |
| メール | 定期通知が送信 | SMTPログ |
| 更新処理 | プラグイン等の定期イベント | イベント一覧 |
system cronへ移した後のrollback
外部cron設定を止め、DISABLE_WP_CRONを元へ戻せば標準WP-Cronへ戻せる設計にしておきます。設定変更日時と旧値を残し、緊急時に管理画面へ入れなくても戻せる経路を確認してください。
公式情報・参考資料
まとめ
WP-Cronは欠陥ではなく、共有サーバーでも定期処理を動かせるWordPressの仕組みです。ただし「アクセスをきっかけに動く」という特性が業務要件と合わない時はsystem cronへ分離する価値があります。時刻の正確さとサーバー負荷を両方見て判断してください。全体の運用基盤は140、更新前の検証は148、高速化全体の入口は150へつなげています。




コメント