Skip to main content

Qu’est-ce qu’une queue

Dans une application web, l’envoi de mails, le redimensionnement d’images ou les appels d’API externes peuvent prendre plusieurs secondes. Traiter cela de manière synchrone dans une requête HTTP fait attendre l’utilisateur inutilement. Les queues Laravel exécutent ces tâches en arrière-plan : la requête retourne immédiatement une réponse, et un worker traite le job à part.
Backends supportés : base de données, Redis, Amazon SQS… En dev, le driver sync exécute les jobs immédiatement, sans queue.

Configuration

config/queue.php

.env

Préparer le driver database

database nécessite une table jobs. Sous Laravel 11+, la migration est incluse ; sinon :

Préparer le driver Redis

Configurez la connexion Redis dans config/database.php puis installez :

Overflow storage SQS

Amazon SQS limite la taille de payload. Pour de gros payloads, redirigez l’excédent vers un cache et n’envoyez qu’un pointeur.
  • enabled : payloads ≥ 1 Mo → cache.
  • always: true : toujours passer par le cache.
  • delete_after_processing : nettoie le cache après succès (true par défaut).
  • flush_on_clear: true : queue:clear purge le cache d’overflow. À combiner avec un store dédié pour ne pas vider le cache général.

Créer une classe de job

Commande make:job

Le fichier app/Jobs/SendWelcomeEmail.php est créé.

Structure

ShouldQueue indique un traitement asynchrone. Le trait Queueable fournit les méthodes nécessaires.
Passer un modèle Eloquent au constructeur sérialise seulement son ID. Au moment de l’exécution, le modèle est récupéré à jour : payload allégé.

Dispatch

dispatch()

Dispatch différé

dispatchAfterResponse()

Exécute le job après l’envoi de la réponse HTTP. Fonctionne aussi en sync — idéal pour du léger sans worker.

Vers une queue précise

Routing de queue

Pour rediriger par défaut certaines classes vers une connexion/queue précise, utilisez Queue::route() dans boot().
Ciblez interface, trait, classe parente… tout ce qui les implémente/étend est routé. Plusieurs routes en une :
Un onQueue() / onConnection() explicite sur le job prime sur le routing.

Transfert de queues (Queue::forward())

Queue::forward() transfère les jobs d’une queue vers une autre queue ou connexion. Pratique pour changer d’infrastructure de queues sans modifier chaque job ni le code appelant.
Passez un tableau pour transférer plusieurs queues à la fois.
Si le job spécifie explicitement une connexion, ce réglage prime sur la configuration de transfert.

Sync (dev/tests)

dispatchSync() exécute immédiatement, sans queue.

Bulk dispatch

Pour envoyer beaucoup de jobs indépendants d’un coup sans tracking : Bus::bulk().
Bus::bulk() groupe les jobs par connexion/queue et les envoie par lot. Contrairement à Bus::batch(), pas de suivi ni de callback.

Chaînes de jobs

Le chaînage permet d’exécuter plusieurs jobs dans l’ordre. Si un job de la chaîne échoue, les jobs suivants ne sont pas exécutés.
Vous pouvez aussi ajouter un callback exécuté lorsque la chaîne entière est terminée, ou lorsqu’un job de la chaîne échoue.

Batches de jobs

Les batches permettent de dispatcher plusieurs jobs d’un coup tout en suivant la progression globale. Commencez par créer la migration pour la table job_batches.
Utilisez le trait Batchable dans la classe de job.
Dispatchez le batch avec Bus::batch() et enregistrez des callbacks de succès, d’échec et de fin.
L’ID du batch permet d’en consulter l’état.

Traiter les jobs

queue:work

Ciblez driver et file :
queue:work reste actif. Après un changement de code, queue:restart recharge les workers. En production, un superviseur (Supervisor…) est recommandé.

Options de supervision

Retry paramétré côté job

Souvent plus lisible que la CLI.

Compter les crashs comme des exceptions

Par défaut, les tentatives qui se terminent par un crash ou un arrêt forcé du processus worker, par exemple à cause d’un manque de mémoire, ne sont pas comptées dans le nombre maximal d’exceptions du job (MaxExceptions). Si vous voulez que ces tentatives soient aussi comptées comme des exceptions, ajoutez l’attribut CountCrashesAsExceptions à la classe du job.
Avec cet attribut, le worker enregistre un marqueur dans le cache de l’application pendant le traitement du job. Si le marqueur est toujours présent lors de la tentative suivante, la tentative précédente est comptée comme une exception.

Contrôler l’exécution avec des middlewares de job

Les middlewares de job permettent d’extraire une logique transverse (limitation de débit, prévention des exécutions concurrentes…) hors de la méthode handle() et de la déclarer de façon déclarative via la méthode middleware(). Comme la logique ne vit plus dans le corps du job, il devient facile de réutiliser les mêmes contrôles sur plusieurs jobs.
Générez vos propres middlewares de job avec la commande Artisan make:job-middleware. Les middlewares de job s’utilisent aussi sur les écouteurs d’événements en queue, les mailables et les notifications.

Limitation de débit (RateLimited)

Définissez la limite avec la méthode for de la façade RateLimiter, puis appliquez le middleware Illuminate\Queue\Middleware\RateLimited au job.
Les jobs qui dépassent la limite sont automatiquement remis dans la queue en fonction du temps restant avant réinitialisation. Vous pouvez fixer un délai avec releaseAfter(), ou empêcher toute nouvelle tentative avec dontRelease().
Un job libéré compte toujours dans le nombre de tentatives (attempts). Réglez #[Tries] ou retryUntil() en conséquence.
Si vous utilisez Redis, Illuminate\Queue\Middleware\RateLimitedWithRedis offre une variante plus performante.

Prévention des exécutions concurrentes (WithoutOverlapping)

Illuminate\Queue\Middleware\WithoutOverlapping empêche plusieurs instances du même job de s’exécuter simultanément sur une clé donnée. Utile lorsqu’une ressource ne doit être mise à jour qu’une seule à la fois.
Les jobs en doublon sont remis dans la queue ; releaseAfter() définit l’intervalle avant réessai, et dontRelease() les supprime immédiatement. Comme les verrous s’appuient sur les verrous atomiques, pensez à préciser une expiration avec expireAfter() afin qu’un job qui échoue ou dépasse son délai ne laisse pas un verrou coincé.
Par défaut, le verrouillage n’agit qu’à l’intérieur d’une même classe de job. Pour partager la clé de verrou entre plusieurs classes de jobs, utilisez la méthode shared().

Étouffer les exceptions en rafale (ThrottlesExceptions)

Illuminate\Queue\Middleware\ThrottlesExceptions sert aux jobs qui interagissent avec des services instables (API externes…) : dès qu’un certain nombre d’exceptions se produisent, l’exécution est mise en pause pendant un temps donné. On l’associe généralement à une limite d’essais dans le temps via retryUntil().
when() permet de cibler certaines exceptions seulement, et deleteWhen() supprime le job lorsqu’une exception précise est levée.
Avec Redis, Illuminate\Queue\Middleware\ThrottlesExceptionsWithRedis propose une implémentation plus efficace.

Libération de job (middleware Release)

Pour renvoyer le job dans la queue sans l’exécuter, sous condition, utilisez le middleware Release.
Release::unless() libère si la condition est false.
Une closure pour des cas plus complexes :
Chaque libération incrémente le compteur d’essais. Réglez #[Tries] ou $tries en conséquence.

Jobs échoués

Table failed_jobs

Après épuisement des tentatives, le job est stocké dans failed_jobs.

Cleanup à l’échec

Définissez failed() sur le job.

Arrêter les retries par type d’exception

Utilisez dontRetry dans withExceptions() (fichier bootstrap/app.php).
Avec une closure pour un contrôle fin :
Idéal pour des cas où retenter ne changera rien (validation, échec de paiement, abonnement expiré…).

Lister les échecs

Retry

Suppression

Drivers courants

database

Simple à mettre en place, utilise la RDBMS existante.
  • Avantages : setup rapide, sans dépendance
  • Inconvénients : lourd pour de gros volumes

redis

Driver rapide, très utilisé en production. Débit supérieur.
  • Avantages : rapide, scalable
  • Inconvénients : nécessite Redis
En production, Laravel Horizon offre un beau dashboard pour surveiller les jobs Redis en temps réel.

Supervisor en production

Sous Linux, faites tourner queue:work en continu avec Supervisor.
numprocs=2 démarre 2 workers en parallèle. Rechargez Supervisor :

Exemple : envoi d’e-mail en queue

1

Créer le job

2

Implémenter

3

Dispatcher depuis un contrôleur

4

Démarrer un worker

Récapitulatif

  • Envoi de mails / SMS
  • Redimensionnement d’images / vidéos
  • Appels d’API externes
  • Génération de rapports / exports CSV
  • Envoi de webhooks
QUEUE_CONNECTION=sync dans .env exécute immédiatement — pas besoin de worker pour tester.
Dernière modification le 29 septembre 2026