cronジョブは、WordPressサイトで定期的に決まった時間、日付、間隔でタスクを実行するのに使用されます。WordPressのcronジョブの例としては、投稿の公開、更新のチェック、バックアッププラグインのスケジュール設定などがあります。
WordPressでは通常、このような処理に、システムcronをシミュレートしたWP-Cronを使用します。便利な機能ではありますが、サイトへのトラフィック量によっては、組み込みのcronハンドラを使用するとページの表示時間に悪影響が出てしまう可能性があります。
そこで今回は、WP-Cron(wp-cron.php)を無効にし代わりにシステムcronを使用する方法をご紹介します。
WP-Cronを無効にする理由
Kinstaでは、多くの高トラフィックサイトや負荷の高いサイトを運用しています。その中で、WordPress標準のCronハンドラである「WP-Cron」に起因するパフォーマンス上の問題を数多く目にしてきました。
まず理解しておきたいのは、WP-Cronは本物のcronジョブではないということです。これは、システムのcronジョブの動作を再現するためにWordPressが独自に実装した仕組みです。
WP-Cronは常時実行されているわけではありません。デフォルトでは、ページが読み込まれるたびにwp-cron.phpが実行されます。そのため、アクセス数の多いサイトでは問題が発生することがあります。十分なPHPスレッドが確保されていない場合、リクエストの受信時にWordPressがCron処理を起動しても、利用可能なPHPスレッドが空くまで待機しなければならず、その間は処理が滞留してしまいます。
逆のケースもあります。アクセス数が少ないサイトでは、ページが読み込まれなければWP-Cronも実行されないため、スケジュールされたタスクが予定どおりに実行されない可能性があります。
さらに、WP-Cronを無効化する理由はパフォーマンスだけではありません。セキュリティ上の観点もあります。wp-cron.phpは公開アクセス可能なファイルであるため、誰でも https://yourdomain.com/wp-cron.phpにリクエストを送信して実行をトリガーできます。
標的となったサイトでは、この仕組みを利用してサーバー負荷を繰り返し発生させることが可能です。単純ではあるものの、サイトの応答速度を低下させたり、不安定な状態にしたりするには十分効果的な手法です。WP-Cronを無効化することで、このようなリスクを根本的に排除できます。
WordPressでWP-Cronを無効化する方法(2ステップ)
以下の手順で対応してください(この順番が重要です)。
- WP-Cronの代わりとなるサーバーレベルのcronジョブを設定する
wp-config.phpでWP-Cronを無効化する
先にWP-Cronを無効化すると、スケジュール投稿やバックアップなどの定期タスクが実行されなくなります。エラーは表示されないため、問題に気づきにくい点にも注意が必要です。
ステップ1. サーバーレベルのcronジョブを設定する
WP-Cronが抱える問題を理解したところで、次はその代替となる仕組みを設定しましょう。システムのcronジョブはあらかじめ設定したスケジュールに従って実行されるため、WordPress公式のプラグイン開発者向けドキュメントでも推奨されています。
以下から、ご利用のサーバー環境に合った方法を選択してください。
cPanelを利用している場合
cPanelを利用しているサーバーでは、コントロールパネルからシステムcronジョブを作成できます。まず、cPanelにログインします。次に、「Advanced(詳細設定)」セクションにある「Cron Jobs(cronジョブ)」をクリックしてください。

「Add New Cron Job(cronジョブを追加)」セクションでは、「1時間に2回」や「週に1回」など、あらかじめ用意された実行スケジュールから選択できます。なお、cronジョブの実行頻度にはサーバー事業者ごとに制限が設けられている場合があります。共用サーバー環境では、「1時間に2回」が一般的な設定です。

以下のコマンドを追加します。https://domain.com の部分は、ご自身のドメインに置き換えてください。なお、このコマンドはサーバー環境によって若干異なる場合があります。設定後、「Add New Cron Job」をクリックします。
wget -q -O - https://domain.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

上記コマンドの>/dev/null 2>&1の部分は、cronジョブの実行時に送信されるメール通知を無効化するためのものです。
SSHとcrontabを使用する場合
サーバーへのSSHアクセス権限がある場合は、サーバーのcrontabに直接cronジョブを設定できます。この方法は、使用しているコントロールパネルに関係なく、Linuxベースのサーバーで利用可能です。
SSHでサーバーに接続し、以下のコマンドを実行してください。
crontab -e
次に、以下のいずれか1行を追加します(いずれか1つを選択してください)。
wgetを使用する場合(すべてのサーバーで利用可能)
*/15 * * * * wget -q -O - https://yourdomain.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
PHPを直接実行する場合(HTTPリクエストを介さないため、わずかに高速)
*/15 * * * * php /path/to/wordpress/wp-cron.php >/dev/null 2>&1
yourdomain.comは実際のドメイン名に、/path/to/wordpressはWordPressのインストールパスに置き換えてください。また、*/15はcronジョブを15分ごとに実行する設定です。これは多くのサイトで推奨される一般的な設定です。
WP-CLIを使用する場合
WP-CLIを利用している場合は、この方法が最もシンプルです。WP-CLIのcronコマンドは、実行時刻を迎えたイベントのみを処理するため、wp-cron.phpを直接呼び出すよりも効率的です。crontab -eを実行し、以下の設定を追加してください。
*/15 * * * * cd /path/to/wordpress && wp cron event run --due-now --allow-root >/dev/null 2>&1
また、WP-CLIを使用すると、cronイベントを実行することなく、現在登録されているスケジュール済みタスクをいつでも確認できます。
wp cron event list
これはトラブルシューティング時に便利です。保留中のcronイベントの一覧に加え、それぞれの実行予定時刻や関連付けられているフックを確認できます。
サードパーティツールを利用する場合
サーバー上でcronジョブを設定することに不安がある場合や、利用中のサーバー環境でcronジョブへのアクセスが提供されていない場合は、EasyCronのようなサードパーティサービスを利用することもできます。
重要)WordPressマルチサイトの場合
WordPressマルチサイトでは、cronの仕組みが少し異なります。
WP-Cronはメインサイトだけでなく、各サブサイトごとに実行する必要があります。メインドメインのwp-cron.phpのみを対象にサーバーレベルのcronジョブを設定した場合、別のドメインやサブディレクトリで運用されているサブサイトのcronタスクが正常に実行されない可能性があります。
このような環境では、マルチサイトに標準対応しているWP-CLIを使用する方法が最もシンプルです。
*/15 * * * * cd /path/to/wordpress && wp cron event run --due-now --url=https://yourdomain.com --allow-root >/dev/null 2>&1
サブサイト数が多いネットワークでは、以下のコマンドを使用してすべてのサブサイトを順番に処理できます。
*/15 * * * * cd /path/to/wordpress && wp site list --field=url | xargs -I % wp cron event run --due-now --url=% --allow-root >/dev/null 2>&1
なお、wp-config.phpのDISABLE_WP_CRON定数は、マルチサイト環境でも通常のWordPressサイトと同じように機能します。一度設定すれば、ネットワーク全体に適用されます。
ステップ2. wp-config.phpでWP-Cronを無効化する
WP-Cronを無効化するには、wp-config.phpファイル内の「That’s all, stop editing! Happy blogging.」という行の直前に、以下のコードを追加します。
define('DISABLE_WP_CRON', true);

ファイルを保存すれば設定は完了です。以降、WP-Cronはページの読み込み時に実行されなくなります。
この定数は、ページの読み込み時にWP-Cronが実行されるのを無効化するものです。一方で、wp-cron.phpへの直接アクセスまで無効化するわけではありません。そのため、手順1で設定したサーバーレベルのcronジョブからは、これまでどおり正常にwp-cron.phpを実行できます。
正常に動作していることを確認する方法
2つの手順を完了したら、WP-Cronが正しく無効化されていること、そしてサーバーレベルのcronジョブが正常に実行されていることを確認しましょう。
方法1. WP Crontrolプラグインを使用する
無料のWP Crontrolプラグインをインストールして有効化します。その後、WordPress管理画面の「ツール」>「Cron Events」を開いてください。
ここには、現在スケジュールされているcronイベントの一覧が表示されます。WP-Cronが正しく無効化されている場合、イベントはページ読み込みのたびに実行されるのではなく、サーバーレベルのcronジョブで設定した間隔でのみ実行されるようになります。
方法2. WP-CLIで確認する
サーバー上で以下のコマンドを実行します。
wp cron event list
このコマンドを実行すると、保留中のcronイベントと次回の実行予定時刻を確認できます。イベント一覧に問題がなく、cronジョブの実行ごとに処理待ちのイベントが適切に消化されているようであれば、設定は正常に機能しています。
方法3. サーバーログを確認する
crontabを設定した場合は、一時的に出力先をログファイルへ変更して、cronジョブが実行されていることを確認できます。
*/15 * * * * wget -q -O - https://yourdomain.com/wp-cron.php?doing_wp_cron >> /tmp/wpcron.log 2>&1
15分後に/tmp/wpcron.logを確認し、ジョブが実行されたことを確認してください。動作確認が完了したら、ログ出力の設定は削除して構いません。
まとめ
WP-Cronを無効化し、代わりにサーバーレベルのcronジョブを使用することは、信頼性の向上、不要な負荷の軽減、そして不要な公開エンドポイントの排除につながるシンプルかつ効果的な改善策です。
また、設定作業の大半を省略したい場合は、Kinstaのようなマネージドサーバーを利用するという選択肢もあります。Kinstaでは、15分ごとにサーバー側でcronジョブが実行されるよう設定されているため、WP-Cronを無効化するだけで、残りの管理はプラットフォーム側に任せることができます。