Comment exécuter des tâches en arrière-plan dans une app web : files d'attente, planificateurs et cron
Pour exécuter des tâches en arrière-plan dans une app web, commencez par distinguer deux types de travaux. Les tâches déclenchées (envoyer un e-mail de bienvenue, traiter un fichier envoyé) peuvent être enregistrées dans une file d'attente de tâches, souvent une table de votre base de données, et prises en charge par un worker qui relance en cas d'échec. Les tâches planifiées (un rapport nocturne, des rappels toutes les 15 minutes) ont besoin de quelque chose qui se déclenche selon un calendrier : la fonction cron d'un hébergeur, ou un planificateur externe qui appelle un point de terminaison protégé de votre app. Rendez toujours les tâches sûres à exécuter deux fois, consignez les échecs, et ne comptez jamais sur un minuteur à l'intérieur d'un serveur qui peut se mettre en veille ou redémarrer.
Ce guide explique les options, le cas d'usage de chacune, et comment les mettre en place avec un créateur d'apps IA, y compris sur les hébergeurs qui passent à zéro.
Ce qui est une tâche en arrière-plan
Tout travail lent, peu fiable ou non nécessaire à la réponse immédiate de l'utilisateur :
- Envoi d'e-mails, de notifications et de reçus
- Redimensionnement d'images, transcodage de vidéos, génération de PDF
- Appels à des API tierces lentes, y compris des modèles d'IA pour les tâches longues
- Import ou synchronisation de données depuis un autre système
- Nettoyage nocturne, rapports et rappels
Faire ce travail dans la requête rend les pages lentes et fragiles : si le fournisseur d'e-mails est en panne, l'inscription de l'utilisateur échoue. Le placer en arrière-plan permet à l'utilisateur d'obtenir une réponse instantanée, et la tâche peut être relancée.
Les options
| Option | Fonctionnement | Avantages | Inconvénients |
|---|---|---|---|
| Lancer et oublier dans le même processus | Répondre, puis poursuivre le travail sur le serveur | Aucune configuration | Perdu si le serveur s'arrête ; pas de nouvelles tentatives |
Minuteur intégré (setInterval, setTimeout) | Un minuteur dans le serveur en cours d'exécution | Trivial | Ne s'exécute pas pendant la mise en veille ; doublons avec plusieurs exemplaires |
| File d'attente en base de données | Tâches enregistrées sous forme de lignes ; un worker les récupère et les exécute | Utilise la base existante ; durable ; facile à inspecter | Vous créez les relances et le verrouillage ; il faut quelque chose pour lancer le worker |
| File dédiée (basée sur Redis ou gérée) | Un service de file plus des workers | Fonctions de relance et de planification éprouvées | Un service de plus à faire tourner et à payer |
| Service hébergé de tâches ou de workflows | Un tiers appelle vos points de terminaison avec relances et planning | Planification et relances gérées pour vous | Dépendance au fournisseur ; un compte et une clé de plus |
| Planificateur externe appelant un point de terminaison | Un minuteur ailleurs envoie une requête HTTP selon le calendrier | Fonctionne sur tout hébergeur, y compris ceux qui passent à zéro | Intervalles minimaux et délais ; protégez le point de terminaison |
| Cron intégré à l'hébergeur | La plateforme exécute une commande selon un calendrier | Simple lorsqu'il existe | Tous les hébergeurs n'en proposent pas |
Il n'y a pas de réponse unique. Une petite app n'a souvent besoin que d'une file en base de données et d'un planificateur externe.
Pourquoi les hébergeurs qui passent à zéro changent la donne
De nombreux hébergeurs modernes mettent votre app en veille lorsque personne ne l'utilise, puis la réveillent à la requête suivante. Cela fait économiser de l'argent, mais un serveur endormi n'exécute aucun code : les minuteurs ne se déclenchent pas et les workers ne scrutent rien. Sur ces hébergeurs, le travail planifié doit démarrer avec une requête entrante, et la source la plus simple de cette requête est un planificateur externe. Chaque appel réveille l'app (et souvent sa base de données), donc un appel toutes les minutes coûte plus cher qu'un appel toutes les 15 minutes. Choisissez la fréquence la plus espacée qui répond au besoin.
Schéma 1 : une file de tâches en base de données
Pour les tâches déclenchées :
- Créez une table
jobs: type, charge utile (JSON), statut (pending,running,done,failed), tentatives, run_after, last_error, horodatages. - Lorsqu'un événement survient, insérez une ligne de tâche dans la même transaction que la modification qui l'a causé, pour qu'elles réussissent ou échouent ensemble.
- Un worker récupère les tâches dues, les marque
running, effectue le travail puis les marquedone. - En cas d'échec, augmentez
attempts, reportezrun_after(par exemple 1, 5 puis 30 minutes) et enregistrez l'erreur. Après un maximum, marquez la tâchefailedet alertez quelqu'un.
Si plusieurs workers peuvent fonctionner en même temps, les tâches doivent être réservées en toute sécurité. Sur Postgres, SELECT ... FOR UPDATE SKIP LOCKED permet à chaque worker de réserver des lignes différentes sans conflit.
Qu'est-ce qui fait tourner le worker ? Sur un serveur toujours allumé, une boucle dans un processus séparé. Sur un hébergeur qui passe à zéro, le point de terminaison planifié du schéma 2 peut traiter un lot de tâches dues à chaque appel.
Schéma 2 : un planificateur externe qui appelle votre app
Pour les tâches planifiées :
- Ajoutez un point de terminaison tel que
POST /api/cron/send-reminders. - Protégez-le : exigez un jeton secret dans un en-tête, stocké comme secret des deux côtés, et rejetez tout le reste.
- Rendez-le idempotent : l'exécuter deux fois dans la même minute ne doit pas envoyer deux rappels. Enregistrez ce qui a été envoyé.
- Gardez chaque appel court : traitez un lot (disons 100 éléments) et laissez l'appel suivant prendre le reste.
- Configurez un planificateur pour l'appeler.
Choix de planificateurs :
- Workflows planifiés GitHub Actions. Gratuits dans les limites d'utilisation de GitHub. Selon la documentation GitHub de septembre 2026, l'intervalle minimal est d'une exécution toutes les 5 minutes, les exécutions peuvent être retardées aux heures de pointe (surtout au début de chaque heure), les planifications utilisent UTC par défaut, et les workflows planifiés d'un dépôt public sont désactivés après 60 jours sans activité sur le dépôt.
- Services cron hébergés. Il existe de nombreux services dont le seul rôle est d'appeler une URL selon un calendrier. Vérifiez la fiabilité, l'intervalle minimal et les alertes avant de vous y fier.
- Le planificateur de votre fournisseur cloud. Si vous utilisez déjà un grand fournisseur cloud, il propose un planificateur géré capable d'appeler un point de terminaison HTTPS.
- Un service hébergé de tâches ou de workflows. Ils combinent planification, files et relances, et appellent vos points de terminaison à chaque étape. Comparez les tarifs et les limites sur le site de chaque fournisseur.
Schéma 3 : laisser le fournisseur s'en charger
Parfois, la meilleure tâche en arrière-plan n'en est pas une :
- Paiements. Stripe relance les paiements d'abonnement échoués et envoie des webhooks ; vous réagissez au lieu de scruter. Voir ce qu'est un webhook.
- E-mail. Les fournisseurs mettent en file et relancent la livraison une fois le message transmis.
- Travaux d'IA en volume. OpenAI et Anthropic proposent des API par lots pour les requêtes non urgentes, que vous soumettez et récupérez plus tard.
Prompts à donner à votre créateur d'apps IA
Pour une file d'attente :
Ajoute une file de tâches en arrière-plan utilisant une table jobs dans notre base de données (type, charge utile JSON, statut, tentatives, run_after, last_error). Lorsqu'un utilisateur s'inscrit, insère une tâche send_welcome_email dans la même transaction au lieu d'envoyer l'e-mail directement. Ajoute une fonction processJobs(limit) qui réserve les tâches dues avec SELECT ... FOR UPDATE SKIP LOCKED, les exécute, et relance les échecs après 1, 5 et 30 minutes, en les marquant failed après 4 tentatives.
Pour un déclencheur planifié :
Ajoute POST /api/cron/tick protégé par un jeton bearer provenant du secret CRON_SECRET ; rejette toute requête qui n'en a pas. À chaque appel, exécute processJobs(100) et envoie les rappels de réservation prévus dans les 24 prochaines heures qui n'ont pas encore été envoyés, en enregistrant les rappels envoyés pour qu'aucun ne soit envoyé deux fois. Renvoie un résumé JSON de ce qui a été exécuté. Écris ensuite un workflow GitHub Actions qui appelle ce point de terminaison toutes les 15 minutes, en lisant l'URL et le jeton depuis les secrets du dépôt.
Erreurs courantes
- Compter sur
setInterval. Il s'arrête silencieusement lorsque le serveur se met en veille ou redémarre, et se double lorsque deux exemplaires tournent. - Un point de terminaison cron non protégé. Toute personne qui le trouve peut déclencher vos tâches, ou faire grimper votre facture d'e-mails.
- Des tâches non idempotentes. Les relances et les appels en double du planificateur finiront par arriver. Concevez en conséquence.
- Aucune visibilité sur les échecs. Une tâche qui échoue silencieusement pendant une semaine est pire qu'une tâche qui échoue bruyamment. Journalisez les erreurs et alertez en cas d'échecs répétés.
- Des exécutions longues dans une seule requête. Les requêtes expirent. Traitez par lots.
- Planifier trop souvent. Chaque appel sur un hébergeur qui passe à zéro réveille l'app et la facture. Adaptez l'intervalle au besoin réel.
- Fuseaux horaires. « 9 h » n'a pas la même signification pour votre planificateur (souvent UTC) et pour vos utilisateurs. Stockez les heures en UTC et convertissez-les pour chaque utilisateur.
- Secrets dans le fichier de workflow. Gardez les jetons dans le magasin de secrets du planificateur. Voir comment protéger vos clés d'API.
Liste de contrôle
- Le travail lent est sorti des requêtes utilisateur
- Les tâches sont stockées de façon durable, pas seulement en mémoire
- Relances avec délais croissants et maximum défini
- Chaque tâche peut être exécutée deux fois sans problème
- Le point de terminaison planifié est protégé par un jeton secret
- Chaque exécution traite un lot de taille bornée
- Les tâches échouées sont visibles, avec des alertes
- L'intervalle de planification est choisi en tenant compte du coût d'hébergement
- Les heures sont stockées en UTC
Tâches en arrière-plan dans Mythex
La documentation de Mythex ne décrit pas les tâches planifiées ni les tâches cron, et les apps publiées ainsi que leurs bases de données se mettent en veille lorsqu'elles sont inactives, puis se réveillent à la requête suivante (voir Limites d'hébergement). Ne comptez donc pas sur des minuteurs dans votre app. L'approche qui fonctionne est celle décrite plus haut : demandez à l'agent une table de tâches et un point de terminaison protégé par jeton, puis configurez un planificateur externe pour appeler votre URL publiée. Conservez le jeton comme secret de projet, et gardez à l'esprit que chaque réveil consomme des crédits pendant le temps où l'app et la base sont éveillées, choisissez donc un intervalle raisonnable. Si votre app a besoin d'un backend d'API pour cela, la recette backend d'API REST sert de point de départ, et comment créer une API REST explique la conception des points de terminaison. Si les workers ou bots toujours actifs sont au cœur de votre produit, un hébergeur conçu pour les processus persistants pourrait mieux vous convenir.
Questions
Qu'est-ce qu'une tâche en arrière-plan ?
Une tâche en arrière-plan est un travail que l'app effectue en dehors de la requête pour laquelle l'utilisateur attend, comme envoyer des e-mails, redimensionner des images, générer des rapports ou synchroniser des données. L'utilisateur obtient une réponse rapide, la tâche s'exécute séparément et peut être relancée en cas d'échec.
Comment exécuter une tâche planifiée si mon hébergeur n'a pas de cron ?
Ajoutez un point de terminaison protégé qui effectue le travail, puis faites-le appeler par un planificateur externe selon un calendrier. Les options comprennent un workflow GitHub Actions planifié, un service cron hébergé ou le planificateur de votre fournisseur cloud. Protégez le point de terminaison par un jeton secret.
Puis-je utiliser setInterval ou setTimeout pour les tâches planifiées ?
Uniquement pour de petites tâches peu importantes, sur un serveur toujours en marche. Si le serveur redémarre, passe à zéro ou fonctionne en plusieurs exemplaires, les minuteurs sont perdus ou s'exécutent plusieurs fois. Stockez les travaux planifiés dans une base de données ou utilisez un planificateur.
Mythex prend-il en charge les tâches cron ?
La documentation de Mythex ne décrit pas les tâches planifiées ni les tâches cron, et les apps publiées se mettent en veille lorsqu'elles sont inactives. L'approche fiable consiste à faire appeler par un planificateur externe un point de terminaison protégé de votre app, ce qui réveille l'app et exécute le travail.