queue:prune-failed — 失敗したジョブを削除するコマンド

artisan

php artisan queue:prune-failed

queue:prune-failedfailed_jobs テーブル から古い失敗ジョブを削除する Artisan コマンドです。
失敗ジョブが大量に残ると DB が肥大化し、パフォーマンスに影響します。定期的に実行してテーブルをスリムに保ちましょう。


使い方(最小構成)

# 24 時間以上前に失敗したジョブを全削除
php artisan queue:prune-failed --hours=24
  • --hours は削除対象となる失敗ジョブの最小経過時間(単位は時間)
  • デフォルトは 24(1 日)
  • 実行すると ✅ Deleted X failed job(s) older than 24 hour(s) という確認メッセージが表示されます

コマンドの内部動作

項目 内容
シグネチャ queue:prune-failed {--hours=24}
実装ファイル app/Console/Kernel.php で登録
削除ロジック DB::table('failed_jobs')->where('failed_at', '<', now()->subHours($hours))->delete()
利用可能バージョン Laravel 8 以降(Laravel 12 でも動作)

定期実行(スケジューラ)

// app/Console/Kernel.php

use Illuminate\Support\Facades\Schedule;
use Illuminate\Queue\Console\PruneFailedJobsCommand;

protected function schedule(Schedule $schedule)
{
    // 毎時間実行
    $schedule->command(PruneFailedJobsCommand::class)->hourly();
}

ポイント
・Supervisor や systemd で scheduler を常駐させる
--hours の値を業務に合わせて調整


関連 Artisan コマンド

コマンド 目的
queue:failed 失敗したジョブ一覧を表示
queue:retry 指定ジョブを再投入
queue:forget 指定ジョブを failed_jobs から削除
queue:flush すべてのキュージョブを削除(failed_jobs ではない)
queue:listen 開発環境でジョブを待ち受け
queue:work 実際にジョブを処理

よくある落とし穴

落とし穴 対策
スケジューリングを忘れる 定期実行を必ず設定
--hours を不適切に設定 適切な保持期間を設定(例:48 時間)
マイグレーションを忘れる php artisan queue:failed-table でテーブル作成後に migrate
キュー全体ではなく失敗ジョブだけを削除する 目的に合わせて queue:flush と併用

Pest テスト例

// tests/Feature/QueuePruneFailedCommandTest.php

<?php

use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Carbon;
use Illuminate\Queue\Failed\FailedJobProviderInterface;

uses(Pest\Laravel\RefreshDatabase::class);

it('prunes old failed jobs', function () {
    // 失敗ジョブを 2 件登録
    $provider = app(FailedJobProviderInterface::class);
    $provider->log('TestFailedJob', ['data' => 1], 'job1', 'queue1');
    $provider->log('TestFailedJob', ['data' => 2], 'job2', 'queue2');

    // 1 件を 48 時間前に作成
    DB::table('failed_jobs')
        ->where('id', 1)
        ->update(['failed_at' => Carbon::now()->subHours(48)]);

    // 24 時間以上前のジョブを削除
    Artisan::call('queue:prune-failed', ['--hours' => 24]);

    // 1 件だけ残ることを確認
    expect(DB::table('failed_jobs')->count())->toBe(1);

    // コンソール出力をチェック
    expect(Artisan::output())->toContain('✅ Deleted 1 failed job(s)');
});

テスト実行は vendor/bin/pest で確認できます。
--hours オプションが正しく機能し、古いジョブだけが削除されることを保証します。


参考リンク


まとめ

php artisan queue:prune-failed は、失敗ジョブを定期的に除去して DB をスリムに保つための最小構成です。

  • --hours を適切に設定
  • Scheduler で自動化
  • 失敗ジョブ以外のクリーンアップは queue:flush と併用

これで failed_jobs テーブルが肥大化せず、キュー全体のパフォーマンスを維持できます。

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする