Image de couverture : Background jobs en PHP/Symfony : arrêtez de faire attendre vos utilisateurs
PHP & Frameworks

Background jobs en PHP/Symfony : arrêtez de faire attendre vos utilisateurs

29 juillet 2026
6 min de lecture
6 vues
Sébastien Muler

Votre application rame ? La faute à ce que vous faites dans la requête

Un utilisateur clique sur "S'inscrire". Il attend. Deux secondes. Trois. Le spinner tourne. Ce qu'il ne sait pas, c'est que votre serveur est en train d'envoyer un email de bienvenue, de redimensionner sa photo de profil, et de synchroniser ses données avec Stripe — tout ça dans la même requête HTTP.

C'est le cas classique qui justifie les background jobs : déléguer à un processus séparé tout ce qui n'a pas besoin d'être terminé avant de répondre à l'utilisateur. Envoyer un email, générer une facture PDF, appeler une API tierce, nettoyer des données la nuit — rien de tout cela ne devrait bloquer votre cycle requête/réponse.

L'article source publié sur DEV Community dresse un panorama des meilleurs outils de background jobs en 2026, principalement autour de l'écosystème Laravel. Voici notre lecture côté PHP/Symfony, avec les questions à se poser avant de choisir un outil.

Ce qu'un bon système de queuing doit garantir

Avant de comparer les outils, posons les bases. Un système de background jobs sérieux répond à quatre exigences fondamentales.

Durabilité : si le processus worker meurt (redémarrage serveur, crash, déploiement), le job ne disparaît pas. Il est persisté quelque part — base de données, Redis, broker de messages — et sera repris.

Retry automatique : un appel à une API externe qui timeout ne devrait pas condamner définitivement le job. Le système doit réessayer, idéalement avec un backoff exponentiel pour ne pas marquer l'API défaillante.

Dead-letter queue : les jobs qui échouent définitivement après N tentatives doivent atterrir quelque part d'inspecable, pas disparaître silencieusement. C'est votre filet de sécurité.

Observabilité : savoir combien de jobs sont en attente, lesquels ont échoué, combien de temps ils ont pris — c'est non négociable en production.

Si votre solution actuelle ne coche pas ces quatre cases, vous avez une dette technique qui finira par vous coûter des données perdues ou des clients mécontents.

Symfony Messenger : votre premier choix par défaut

Si vous développez en Symfony, vous avez déjà la réponse intégrée : Symfony Messenger. C'est le composant officiel de messaging du framework, mature, extensible, et documenté exhaustivement.

Le principe est simple : vous créez un message (un objet PHP simple), vous le dispatchez via le bus, et un handler le traite — soit de manière synchrone, soit de manière asynchrone via un transport configuré.

// Dispatcher le message dans votre contrôleur
$this->bus->dispatch(new SendWelcomeEmailMessage($user->getId()));
// Le handler s'exécute dans le worker
class SendWelcomeEmailHandler implements MessageHandlerInterface
{
    public function __invoke(SendWelcomeEmailMessage $message): void
    {
        // Envoi de l'email — sans bloquer l'utilisateur
    }
}

Messenger supporte nativement plusieurs transports : Doctrine (stockage en base de données, zéro dépendance supplémentaire), Redis, AMQP (RabbitMQ), et Amazon SQS. Pour une application PHP classique avec PostgreSQL ou MySQL déjà en place, le transport Doctrine est souvent suffisant pour démarrer.

Le worker se lance avec une commande simple :

php bin/console messenger:consume async --time-limit=3600

En production, vous le supervisez avec Supervisor ou systemd pour qu'il redémarre automatiquement. Les retries et la dead-letter queue se configurent en quelques lignes YAML.

Quand Doctrine suffit, quand Redis s'impose

Pour la majorité des projets PHP/Symfony avec un volume modéré (quelques centaines à quelques milliers de jobs par heure), le transport Doctrine est largement suffisant. Pas de service supplémentaire à maintenir, les jobs sont visibles directement en base, les transactions ACID garantissent la durabilité.

Passez à Redis quand :

  • Vous avez des pics importants et avez besoin de throughput élevé
  • Vous voulez utiliser l'interface Horizon (si vous venez de Laravel)
  • Vous avez déjà Redis en place pour le cache

Les alternatives intéressantes pour PHP en 2026

L'article source mentionne plusieurs outils populaires dans l'écosystème JavaScript/Laravel. Voici comment les mapper sur des équivalents ou alternatives pertinentes en PHP :

Laravel Queues reste la référence dans son écosystème, avec Horizon pour le monitoring. Si votre stack est Laravel, c'est votre solution native — l'équivalent direct de Symfony Messenger.

QStash (par Upstash) est une option intéressante pour les architectures serverless ou les applications hébergées sur des plateformes sans processus persistants. Il expose une API HTTP : vous envoyez un webhook différé, QStash se charge du retry et de la livraison. Utile si vous ne pouvez pas faire tourner un worker long.

Trigger.dev et Inngest sont des solutions modernes orientées workflows, avec un modèle événementiel et un dashboard intégré. Ils ciblent surtout l'écosystème Node.js, mais l'idée — des jobs durables déclenchés par des événements — peut inspirer votre architecture en PHP avec Messenger et ses middlewares.

Pour le self-hosting pur, Symfony Messenger avec transport Doctrine ou Redis reste imbattable en PHP : zéro coût, zéro vendor lock-in, et le code reste dans votre application.

Checklist avant de mettre vos premiers jobs en production

Quelques points souvent oublies qui évitent les mauvaises surprises :

  • Idempotence : votre handler peut-il être exécuté deux fois sans dommage ? En cas de retry, c'est ce qui arrivera.
  • Timeouts : configurez un timeout sur vos handlers pour éviter les workers bloqués indéfiniment sur un appel réseau qui ne répond plus.
  • Monitoring : ajoutez des métriques ou des logs structurés dans vos handlers. Savoir qu'un job a échoué après que le client vous appelle, c'est trop tard.
  • Tests : avec Messenger, le InMemoryTransport permet de tester que les bons messages sont dispatchés sans infrastructure externe.
  • Supervisor en production : configurez numprocs selon votre charge, et pensez à stopwaitsecs pour éviter de tuer des jobs en cours lors d'un déploiement.

Conclusion

Les background jobs ne sont pas une optimisation prématurée : dès que votre application envoie des emails, génère des documents, ou appelle des APIs tierces, les déléguer à un worker est une décision d'architecture de base.

En PHP/Symfony, Messenger est votre point de départ naturel — bien documenté, intégré au framework, et capable de couvrir la majorité des besoins de production. Pour des cas plus complexes (workflows multi-étapes, événements distribués, serverless), les outils comme QStash ou une architecture événementielle plus poussée méritent d'être explorés.

Vos utilisateurs ne devraient jamais attendre qu'un email parte. C'est un principe, pas une option.

Partager cet article