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, séparez d'abord le travail en deux types. Les tâches déclenchées (envoyer un courriel de bienvenue, traiter un téléversement) 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 travailleur doté de nouvelles tentatives. Les tâches planifiées (un rapport quotidien, des rappels toutes les 15 minutes) ont besoin de quelque chose qui se déclenche selon un horaire : la fonction cron d'un hébergeur ou un planificateur externe qui appelle un point d'accès protégé de votre app. Rendez toujours les tâches sans danger si elles s'exécutent deux fois, consignez les échecs, et ne comptez jamais sur une minuterie à l'intérieur d'un serveur qui peut se mettre en veille ou redémarrer.
Ce guide explique les options, quand chacune convient et comment les configurer avec un générateur d'apps IA, y compris sur les hébergeurs qui se mettent à zéro.
Ce qui compte comme tâche en arrière-plan
Tout ce qui est lent, peu fiable ou non nécessaire à la réponse immédiate de l'utilisateur :
- L'envoi de courriels, de notifications et de reçus
- Le redimensionnement d'images, le transcodage de vidéos, la production de PDF
- L'appel à des API tierces lentes, y compris des modèles d'IA pour des tâches longues
- L'importation ou la synchronisation de données depuis un autre système
- Le nettoyage nocturne, les rapports et les rappels
Faire tout cela pendant la requête rend les pages lentes et fragiles : si le fournisseur de courriels est en panne, l'inscription de l'utilisateur échoue. Déplacer le travail 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 dans le serveur | Aucune configuration | Perdue si le serveur s'arrête; pas de nouvelles tentatives |
Minuterie dans le processus (setInterval, setTimeout) | Une minuterie dans le serveur en marche | Trivial | Ne s'exécute pas pendant la mise en veille; doublons avec plusieurs copies |
| File d'attente en base de données | Tâches enregistrées sous forme de lignes; un travailleur les réclame et les exécute | Utilise la base de données existante; durable; facile à inspecter | Vous créez les nouvelles tentatives et le verrouillage; il faut quelque chose pour exécuter le travailleur |
| File dédiée (basée sur Redis ou gérée) | Un service de file et des travailleurs | Fonctions matures de nouvelles tentatives et de planification | Un autre service à exécuter et à payer |
| Service hébergé de tâches ou de workflows | Un tiers appelle vos points d'accès avec des nouvelles tentatives et des horaires | La planification et les nouvelles tentatives sont gérées pour vous | Dépendance envers un fournisseur; un autre compte et une autre clé |
| Planificateur externe qui appelle un point d'accès | Une minuterie ailleurs envoie une requête HTTP selon l'horaire | Fonctionne sur tout hébergeur, y compris ceux qui se mettent à zéro | Intervalles minimums et délais; protégez le point d'accès |
| Cron intégré à l'hébergeur | La plateforme exécute une commande selon un horaire | Simple lorsqu'il existe | Tous les hébergeurs n'en offrent pas |
Il n'existe pas de réponse unique. Une petite app a souvent seulement besoin d'une file en base de données et d'un planificateur externe.
Pourquoi les hébergeurs qui se mettent à zéro changent la donne
De nombreux hébergeurs modernes mettent votre app en veille lorsque personne ne l'utilise, et la réveillent à la requête suivante. Cela fait économiser de l'argent, mais un serveur en veille n'exécute aucun code : les minuteries ne se déclenchent pas et les travailleurs n'interrogent rien. Sur ces hébergeurs, le travail planifié doit commencer par 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); un appel chaque minute coûte donc plus cher qu'un appel toutes les 15 minutes. Choisissez l'horaire le plus espacé qui répond au besoin.
Motif 1 : une file d'attente 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), nombre de tentatives, run_after, last_error, horodatages. - Lorsque quelque chose se produit, insérez une ligne de tâche dans la même transaction que la modification qui l'a causée, pour qu'elles réussissent ou échouent ensemble.
- Un travailleur prend les tâches dues, les marque
running, fait le travail et les marquedone. - En cas d'échec, augmentez
attempts, définissez unrun_afterplus tardif (par exemple 1, 5, puis 30 minutes) et stockez l'erreur. Après un maximum, marquez la tâchefailedet alertez quelqu'un.
Si plusieurs travailleurs peuvent fonctionner en même temps, les tâches doivent être réclamées de façon sécuritaire. Sur Postgres, SELECT ... FOR UPDATE SKIP LOCKED permet à chaque travailleur de réclamer des lignes différentes sans se heurter aux autres.
Qu'est-ce qui exécute le travailleur? Sur un serveur toujours allumé, une boucle dans un processus distinct. Sur un hébergeur qui se met à zéro, le point d'accès planifié du motif 2 peut traiter un lot de tâches dues à chaque appel.
Motif 2 : un planificateur externe qui appelle votre app
Pour les tâches planifiées :
- Ajoutez un point d'accès comme
POST /api/cron/send-reminders. - Protégez-le : exigez un jeton secret dans un en-tête, conservé 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. Consignez ce qui a été envoyé.
- Gardez chaque appel court : traitez un lot (par exemple 100 éléments) et laissez le prochain appel prendre le reste.
- Pointez un planificateur vers ce point d'accès.
Choix de planificateurs :
- Workflows planifiés de GitHub Actions. Gratuits dans les limites d'utilisation de GitHub. Selon la documentation de GitHub en septembre 2026, l'intervalle minimal est de 5 minutes, les exécutions peuvent être retardées aux heures de pointe (surtout au début de chaque heure), les horaires 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é du dépôt.
- Services cron hébergés. Il existe de nombreux services dont la seule fonction est d'appeler une URL selon un horaire. Vérifiez la fiabilité, l'intervalle minimal et les alertes avant de vous y fier.
- Le planificateur de votre fournisseur infonuagique. Si vous utilisez un grand fournisseur infonuagique, il offre un planificateur géré capable d'appeler un point d'accès HTTPS.
- Un service hébergé de tâches ou de workflows. Ils combinent planification, files et nouvelles tentatives, et appellent vos points d'accès pour chaque étape. Comparez la tarification et les limites sur le site de chaque fournisseur.
Motif 3 : laisser le fournisseur s'en charger
Parfois, la meilleure tâche en arrière-plan est aucune tâche :
- Paiements. Stripe relance les paiements d'abonnement échoués et envoie des webhooks; vous réagissez au lieu d'interroger. Voir qu'est-ce qu'un webhook.
- Courriels. Les fournisseurs mettent en file d'attente et relancent la livraison une fois le message transmis.
- Traitement par lots de l'IA. OpenAI et Anthropic offrent des API par lots pour les requêtes non urgentes que vous soumettez et récupérez plus tard.
Instructions à donner à votre générateur d'apps IA
Pour une file d'attente :
Ajoute une file de tâches en arrière-plan qui utilise une table jobs dans notre base de données (type, charge utile JSON, statut, attempts, 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 le courriel en ligne. Ajoute une fonction processJobs(limit) qui réclame 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 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 dus dans les 24 prochaines heures qui n'ont pas encore été envoyés, en consignant 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 d'accès toutes les 15 minutes, en lisant l'URL et le jeton dans les secrets du dépôt.
Erreurs courantes
- S'appuyer sur
setInterval. Il s'arrête silencieusement lorsque le serveur se met en veille ou redémarre, et il se double lorsque deux copies tournent. - Un point d'accès cron non protégé. Quiconque le trouve peut déclencher vos tâches, ou faire grimper votre facture de courriels.
- Des tâches non idempotentes. Les nouvelles tentatives et les appels en double du planificateur arriveront. Concevez en conséquence.
- Aucune visibilité sur les échecs. Une tâche qui échoue en silence 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 se met à zéro réveille l'app et la facture. Adaptez l'intervalle au besoin réel.
- Fuseaux horaires. « 9 h » ne signifie pas la même chose pour votre planificateur (souvent UTC) et pour vos utilisateurs. Stockez les heures en UTC et convertissez-les par utilisateur.
- Secrets dans le fichier de workflow. Gardez les jetons dans le coffre de secrets du planificateur. Voir comment garder vos clés d'API en sécurité.
Liste de vérification
- Le travail lent est sorti des requêtes des utilisateurs
- Les tâches sont stockées de façon durable, et non seulement en mémoire
- Nouvelles tentatives avec délais croissants et un maximum
- Chaque tâche peut être exécutée deux fois sans danger
- Le point d'accès planifié est protégé par un jeton secret
- Chaque exécution traite un lot borné
- 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 cron, et les apps publiées ainsi que leurs bases de données s'endorment lorsqu'elles sont inactives, puis se réveillent à la requête suivante (voir Limites d'hébergement). Ne comptez donc pas sur des minuteries dans votre app. L'approche qui fonctionne est celle décrite plus haut : demandez à l'agent une table de tâches et un point d'accès protégé par jeton, puis pointez un planificateur externe vers l'URL publiée de votre app. Conservez le jeton comme secret du projet, et rappelez-vous que chaque réveil consomme des crédits pendant le temps où l'app et la base de données 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 est un bon point de départ, et comment créer une API REST explique comment concevoir les points d'accès. Si les travailleurs ou les robots permanents 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 fait votre app en dehors de la requête pour laquelle un utilisateur attend, comme l'envoi de courriels, le redimensionnement d'images, la production de rapports ou la synchronisation de données. L'utilisateur obtient une réponse rapide, la tâche s'exécute séparément et peut être relancée si elle échoue.
Comment exécuter une tâche planifiée si mon hébergeur n'a pas de cron?
Ajoutez un point d'accès protégé qui effectue le travail, puis faites appeler ce point d'accès par un planificateur externe selon un horaire. Les options incluent un workflow GitHub Actions planifié, un service cron hébergé ou le planificateur de votre fournisseur infonuagique. Protégez le point d'accès par un jeton secret.
Puis-je utiliser setInterval ou setTimeout pour des tâches planifiées?
Seulement pour de petites tâches peu importantes, sur un serveur toujours en marche. Si le serveur redémarre, se met à zéro ou fonctionne en plusieurs copies, les minuteries sont perdues ou s'exécutent plus d'une fois. Enregistrez le travail planifié 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 cron, et les apps publiées s'endorment lorsqu'elles sont inactives. L'approche fiable consiste à faire appeler un point d'accès protégé de votre app par un planificateur externe, ce qui réveille l'app et exécute le travail.