Skip to main content

キューとは

Webアプリケーションでは、メール送信・画像のリサイズ・外部APIへの問い合わせなど、完了まで数秒かかる処理が発生することがあります。 これをHTTPリクエストの中で同期的に行うと、ユーザーはレスポンスが返るまで待ち続けなければなりません。 Laravelのキューを使うと、こうした重い処理をバックグラウンドで非同期に実行できます。 リクエストはすぐにレスポンスを返し、実際の処理はワーカープロセスが別途こなしてくれます。
キューはデータベース・Redis・Amazon SQSなど複数のバックエンドに対応しています。 開発環境では sync ドライバを使うと、キューを使わずジョブを即時実行できます。

キューの設定

config/queue.php

キューの設定は config/queue.php に集約されています。 QUEUE_CONNECTION 環境変数で使用するドライバを切り替えます。

.env の設定

データベースドライバの準備

database ドライバを使う場合、ジョブを保存するテーブルが必要です。 Laravel 11以降の新規プロジェクトには最初からマイグレーションが含まれていますが、 含まれていない場合は次のコマンドで作成します。

Redisドライバの準備

redis ドライバを使う場合は config/database.php にRedis接続設定を追加し、 Composerでドライバをインストールします。

SQS Overflow Storage

Amazon SQS はメッセージペイロードの最大サイズに制限があります。 ペイロードが大きくなるジョブを扱う場合は、超過分をキャッシュストアに保存し、SQSにはポインターのみを送る設定を追加します。
  • enabled を有効にすると、1MB以上のペイロードを指定したキャッシュストアへ保存します。
  • alwaystrue にすると、サイズに関係なくすべてのSQSペイロードをキャッシュストアに保存します。
  • delete_after_processing はジョブ成功後に保存済みペイロードを削除します(デフォルト true)。
  • flush_on_cleartrue にすると queue:clear 実行時にoverflow用ストアを flush します。通常のキャッシュを消さないため、専用ストアと組み合わせて使ってください。

ジョブクラスの作成

make:job コマンド

make:job Artisanコマンドでジョブクラスのひな型を生成します。
app/Jobs/SendWelcomeEmail.php が生成されます。

ジョブクラスの構造

ShouldQueue インターフェースを実装することで、このジョブがキューで非同期処理されることをLaravelに伝えます。 Queueable トレイトがジョブのキュー操作に必要なメソッドを提供します。
コンストラクタにEloquentモデルを渡すと、Laravelは自動的にIDだけをシリアライズします。 実行時にデータベースから最新データを再取得するため、キューのペイロードが軽くなります。

ジョブのディスパッチ

dispatch()

コントローラやサービスからジョブをキューに送り出すには dispatch() を使います。

遅延ディスパッチ

delay() メソッドでジョブの実行を指定時間後に遅らせられます。

dispatchAfterResponse()

dispatchAfterResponse() を使うと、HTTPレスポンスをユーザーに返した直後にジョブを実行します。 sync ドライバでも動作するため、専用のワーカーが不要な軽量な用途に向いています。

特定のキューへのディスパッチ

Queue Routing

特定のジョブクラスをデフォルトで決まった接続・キューに振り向けるには、ServiceProviderの boot()Queue::route() を使います。ジョブクラスごとに onQueue() / onConnection() を書く代わりに一元管理できます。
インターフェース・トレイト・親クラスも指定できます。それらを実装・使用・継承するすべてのジョブに自動で適用されます。 複数ジョブをまとめてルーティングする場合は配列を渡します。
Queue Routing はジョブ側の onQueue() / onConnection() で上書きできます。

同期実行(テスト・開発用)

dispatchSync() を使うと、キューを経由せずに即時実行します。

バルクディスパッチ

多数の独立したジョブを一度にディスパッチする場合、Bus ファサードの bulk() メソッドを使用できます。バッチ処理のような追跡やコールバックが不要なケースに最適です。 Bus::bulk() は、ジョブを設定されたキュー接続とキュー名でグループ化し、各グループをまとめてキューにプッシュするため効率的です。
Bus::bulk() はジョブをバッチとしてまとめてキューに送信します。バッチ処理(Bus::batch())とは異なり、進捗追跡や完了コールバックは提供されません。独立した大量のジョブをシンプルに一括送信したい場合に適しています。

ジョブの処理

queue:work コマンド

キューワーカーを起動してジョブを処理します。
特定のドライバやキューを指定することもできます。
queue:work は起動したまま動き続けます。コードを変更したときは queue:restart でワーカーを再起動してください。 本番環境ではSupervisorなどのプロセスマネージャーで管理するのが一般的です。

キューワーカーの監視オプション

よく使うオプションを組み合わせてワーカーを細かく制御できます。

ジョブクラスにリトライ設定を書く

コマンドラインオプションより、ジョブクラス自体に設定を書く方が管理しやすい場合があります。

ジョブのリリース(Release ミドルウェア)

特定の条件を満たすときにジョブを実行せずキューに戻したい場合、Release ミドルウェアを使うと簡潔に書けます。
Release::unless() は条件が false のときにリリースします。
クロージャを使うと、より複雑な条件を記述できます。
ジョブをリリースしてもジョブの試行回数はカウントアップされます。#[Tries]$tries プロパティを適切に設定してください。

失敗したジョブの処理

failed_jobs テーブルの準備

ジョブが最大試行回数を超えると、failed_jobs テーブルに記録されます。 テーブルがない場合は次のコマンドで作成します。

失敗時のクリーンアップ

ジョブに failed() メソッドを定義すると、失敗したときの後処理を記述できます。

例外によるリトライ停止

例外の種類によってはリトライさせず即座に失敗させたい場合があります。bootstrap/app.phpwithExceptions() 内で dontRetry を使って対象の例外クラスを指定します。
より細かい制御が必要な場合は dontRetryWhen にクロージャを渡します。クロージャが true を返すとジョブは即座に失敗としてマークされ、リトライされません。
バリデーションエラーや決済失敗(サブスクリプション期限切れなど)のように、何度リトライしても結果が変わらない例外はこの方法で即座に失敗させると効率的です。

失敗したジョブの一覧確認

失敗したジョブのリトライ

失敗したジョブの削除

よく使うキュードライバ

database ドライバ

追加のミドルウェアなしに使い始められるシンプルなドライバです。 jobs テーブルにジョブを保存し、ワーカーがポーリングして処理します。
  • 長所: セットアップが簡単、既存のRDBMSをそのまま使える
  • 短所: データベースへの負荷が高いため、大量のジョブには不向き

redis ドライバ

本番環境で最もよく使われる高速なドライバです。 インメモリで動作するためデータベースよりもスループットが高く、大量のジョブを処理できます。
  • 長所: 高速、スケーラブル
  • 短所: Redisサーバーの用意が必要
Redisキューを本番運用する場合は Laravel Horizon の導入を検討してください。 美しいダッシュボードでジョブの状況をリアルタイムに監視できます。

Supervisorによる本番運用

本番環境では、queue:work プロセスが何らかの理由で停止したときに自動で再起動する仕組みが必要です。 Linux環境では Supervisor を使うのが一般的です。
numprocs=2 で2つのワーカープロセスを並列起動します。 設定後に Supervisor を再読み込みします。

実践例: メール送信をキューで処理する

1

ジョブクラスを作成する

2

ジョブの処理を実装する

3

コントローラからディスパッチする

4

ワーカーを起動する

まとめ

  • メール・SMS送信
  • 画像・動画のリサイズや変換
  • 外部APIへのリクエスト
  • レポートの生成やCSVエクスポート
  • Webhook の送信
.envQUEUE_CONNECTION=sync にすると、ジョブはキューを経由せず即時実行されます。 ワーカーを起動しなくても動作確認できるため、開発中は便利です。
最終更新日 2026年7月9日