EventBridge Scheduler pour les planifications autonomes, les états Wait de Step Functions pour les délais qui vivent au sein d'un workflow, et les anciennes règles cron d'EventBridge uniquement pour les jobs UTC déjà en place que rien n'oblige à migrer. Scheduler a apporté au serverless AWS les fuseaux horaires, les exécutions ponctuelles et les retries par planification ; le cron historique n'offre rien de tout cela. Voici où chaque option gagne, et où le cron naïf casse discrètement deux fois par an.
Pourquoi les règles cron EventBridge cassent-elles au changement d'heure ?
Les expressions cron des règles EventBridge s'évaluent uniquement en UTC. Un rapport prévu à 9 h à Paris part à 9 h en hiver et à 10 h en été, car l'heure UTC ne bouge pas quand l'heure locale change. Les règles ne savent pas non plus exprimer le ponctuel : chaque « lance ça une fois, plus tard » devient un contournement.
Ces limites sont structurelles. Les règles vivent au niveau du bus d'événements, partagent un quota par défaut de quelques centaines de règles par bus, et configurent les retries par cible plutôt que par planification. Pour combler l'absence de ponctuel, on crée une règle, on la laisse se déclencher, puis on la supprime depuis le handler : de la plomberie fragile pour une capacité désormais native. Les règles cron restent un choix raisonnable dans un seul cas : un petit ensemble stable de jobs réellement UTC (exports nocturnes, rotation de logs), déjà déployé, déjà supervisé, et qu'il ne vaut pas la peine de toucher.
Que fait EventBridge Scheduler que les règles cron ne font pas ?
EventBridge Scheduler est un service à part, conçu pour la planification : cron avec fuseau horaire et heure d'été correctement gérée, exécutions ponctuelles via les expressions at(), fenêtres flexibles pour lisser la charge, et des quotas qui se comptent en millions de planifications. Chacune porte sa propre politique de retry et sa file de lettres mortes. En 2026, c'est le choix par défaut.
Sa fonctionnalité la plus sous-estimée : les cibles universelles. Une planification peut appeler directement des centaines de services AWS via leurs API : envoyer un message SQS, démarrer une tâche ECS, lancer une exécution Step Functions, sans Lambda intermédiaire dont le seul rôle serait de relayer l'appel. Moins de fonctions, c'est moins de cold starts, moins de rôles IAM et moins de code à maintenir. Quand la cible est une file qui alimente des workers, la planification s'insère directement dans le schéma de fan-out décrit dans notre article EventBridge, SQS et Lambda, et les livraisons échouées atterrissent dans la file de lettres mortes au lieu de disparaître.
Quand les états Wait de Step Functions battent-ils un scheduler ?
Quand le délai fait partie du workflow. « Attendre trois jours après l'inscription, puis vérifier l'activité et envoyer un e-mail » est une seule exécution qui garde son contexte, pas trois planifications qui reconstruisent l'état depuis une base. Les états Wait se suspendent sur une durée fixe ou sur un horodatage lu dans l'entrée, et les workflows Standard peuvent patienter jusqu'à un an.
La même mécanique couvre les validations humaines : un task token gare l'exécution jusqu'au retour d'appel, qu'il arrive dans une heure ou dans un mois, sans calcul facturé pendant l'attente. Le piège tient au type de workflow : les Express facturent à la durée et plafonnent l'exécution à quelques minutes, les longues attentes vont donc dans Standard. Si vous hésitez entre une machine à états et une chaîne de Lambdas, nous traitons ce compromis dans notre article sur l'orchestration Step Functions. Utilisez Wait pour les délais entre étapes ; utilisez Scheduler pour démarrer le workflow.
Quelle primitive de planification pour votre charge ? Décrivez votre système : diagnostic d'une page sous 48 h.
Recevoir mon diagnostic →Scheduler vs règles cron vs états Wait : le comparatif
Les trois outils se recouvrent à peine une fois l'axe nommé. Règles cron et Scheduler déclenchent tous deux un travail à heure dite, mais seul Scheduler comprend l'heure locale et le ponctuel. Les états Wait ne déclenchent rien : ils suspendent un travail déjà en cours. Le tableau ci-dessous trace les frontières, avec le scénario gagnant de chacun.
| Critère | Règles cron EventBridge | EventBridge Scheduler | Step Functions Wait |
|---|---|---|---|
| Fuseaux horaires | UTC uniquement | Tout fuseau, heure d'été gérée | Horodatages UTC lus dans l'entrée d'état |
| Exécutions ponctuelles | Non supportées | Expressions at() natives, auto-suppression | N'importe quel délai dans une exécution en cours |
| Échelle | Quelques centaines de règles par bus (quota par défaut) | Quotas en millions de planifications | Une attente par étape ; Standard patiente jusqu'à un an |
| Types de cibles | Cibles du bus (Lambda, SQS, SNS, etc.) | Des centaines d'API AWS appelées en direct | Ce que fait l'état suivant |
| Retry et DLQ | Par cible sur la règle | Par planification, avec backoff | Par état, via la gestion d'erreurs du workflow |
| Quand il gagne | Jobs UTC stables existants, rien à migrer | Presque tout le reste : récurrent, rappels, ponctuel | Délais et validations au sein d'un workflow qui garde le contexte |
Comment gérer des rappels par utilisateur sans cron de polling ?
Créez une planification ponctuelle par rappel et laissez-la se supprimer après déclenchement. Cela remplace le design classique où une Lambda cron balaie une table de rappels chaque minute, paie des invocations presque toujours vides, et rate quand même la bonne minute sous charge. Avec des quotas en millions, une planification par utilisateur n'est pas un anti-pattern : c'est l'usage prévu.
// Une planification par rappel, supprimée automatiquement après déclenchement
await scheduler.send(new CreateScheduleCommand({
Name: `reminder-${reminderId}`,
ScheduleExpression: "at(2026-10-05T09:00:00)",
ScheduleExpressionTimezone: "Europe/Paris",
FlexibleTimeWindow: { Mode: "OFF" },
ActionAfterCompletion: "DELETE",
Target: {
Arn: "arn:aws:sqs:eu-west-1:123456789012:reminders",
RoleArn: "arn:aws:iam::123456789012:role/scheduler-to-sqs",
},
}));
Deux détails comptent en production. Gardez le consommateur idempotent, car un retry peut livrer le même rappel deux fois. Et attachez une file de lettres mortes à chaque planification : un rappel échoué devient un message à rejouer, pas un trou silencieux dans votre produit.
Combien coûtent les trois options ?
Des formes de coût, pas des chiffres : Scheduler facture à l'invocation au-delà d'une franchise mensuelle, les règles planifiées relèvent de la tarification EventBridge, et les Step Functions Standard facturent à la transition d'état, si bien qu'un Wait en pause ne coûte rien pendant qu'il dort. Un cron de polling, lui, paie chaque invocation vide, toute la journée, tous les jours.
C'est l'argument économique du schéma de rappels ci-dessus : le polling transforme le temps mort en dépense, quand les planifications par rappel ne paient qu'au moment où quelque chose se produit. Côté workflow, gardez en tête que les Express facturent à la durée, ce qui les rend exactement inadaptés aux longues attentes ; la tarification Step Functions détaille cette répartition. Vérifiez les chiffres du moment sur les pages officielles avant tout chiffrage : franchises et paliers évoluent.
Check-list de décision
- Job récurrent dans un fuseau local, ou toute exécution ponctuelle : EventBridge Scheduler.
- Rappels par utilisateur : une planification auto-supprimée pour chacun, jamais de cron de polling.
- Délai ou validation au sein d'un workflow qui garde le contexte : un état Wait, dans un workflow Standard.
- Règles cron UTC existantes qui tournent bien : laissez-les, migrez à la prochaine intervention.
- Partout : consommateurs idempotents, file de lettres mortes, et une alarme dessus.