Bonjour à tous,
J’exécute une plateforme n8n multi-locataire où chaque locataire se connecte à des API externes avec des limites de débit différentes.
Le défi est que certains locataires ont des limites très basses, tandis que d’autres ont des quotas beaucoup plus élevés.
Configuration actuelle : Webhook → Queue → Worker → API externe
Problèmes observés :
• Certains locataires atteignent les limites de débit beaucoup plus rapidement que d’autres
• Les tentatives créent des pics de trafic
• Un locataire actif peut consommer une grande part de la capacité des workers
• Difficile d’appliquer une utilisation équitable entre les locataires
Je considère :
• Des queues par locataire
• La limitation de débit par seau à jetons / seau qui fuit
• Des compteurs Redis
• Des workers dédiés pour les locataires à haut volume
Pour les équipes exécutant des automations multi-locataires à grande échelle :
• Comment appliquez-vous les limites de débit par locataire ?
• Isolez-vous les queues par locataire ou utilisez-vous une queue partagée avec throttling ?
• Des motifs recommandés pour empêcher qu’un locataire n’affecte les autres tout en maintenant un bon débit ?
Décrivez le problème/l’erreur/la question
Quel est le message d’erreur (le cas échéant) ?
Veuillez partager votre workflow
(Sélectionnez les nœuds sur votre canvas et utilisez les raccourcis clavier CMD+C/CTRL+C et CMD+V/CTRL+V pour copier et coller le workflow.)
Partagez la sortie retournée par le dernier nœud
Informations sur votre configuration n8n
- Version n8n :
- Base de données (par défaut : SQLite) :
- Paramètre n8n EXECUTIONS_PROCESS (par défaut : own, main) :
- Exécution de n8n via (Docker, npm, n8n cloud, application de bureau) :
- **Système d’exploitation :"
Salut @Decoure_Ryan une approche courante est d’utiliser une limitation de débit par tenant au lieu d’une seule limite globale.
Webhook → Queue → Rate Limit Check → Worker → API
Suivez les demandes par tenant en utilisant Redis ou une base de données, et traitez les tâches uniquement lorsque ce tenant respecte sa limite autorisée.
Cela aide à Empêcher un tenant d’affecter les autres
Gérer différentes limites d’API par tenant
Réduire les pics causés par les tentatives
Pour les tenants à haut volume : Files d’attente séparées
Trvailleurs dédiés afin que leur trafic n’impacte pas tout le monde.
Bienvenue @Decoure_Ryan dans notre communauté ! Je m’appelle Jay et je suis un créateur certifié n8n.
L’approche la plus pratique spécifique à n8n ici est d’utiliser un nœud Code avant chaque appel d’API externe pour vérifier et mettre à jour un compteur par tenant. Si tu utilises Redis, stocke la clé sous la forme rate_limit:{tenantId} avec une fenêtre d’expiration correspondant à la période de réinitialisation de l’API - incrémente à chaque demande, et si le tenant dépasse la limite, achemine vers un nœud Wait au lieu de procéder.
Pour le problème de burst de retry : au lieu d’utiliser la retry intégrée de n8n (qui s’exécute immédiatement et peut amplifier les 429), capture la sortie d’erreur du nœud HTTP Request et achemine-la vers un nœud Wait avec un délai fixe ou dynamique extrait de l’en-tête de réponse Retry-After, puis boucle vers la demande.
Si tu es en mode queue, les limites de concurrence par workflow te donnent une isolation naturelle par tenant quand les jobs de chaque tenant s’exécutent dans un sous-workflow dédié - définis concurrency: 1 par workflow tenant et la queue gère l’étranglement pour toi sans aucune logique de compteur Redis.
Voici certaines choses qui ont fonctionné à grande échelle :
Les files d’attente par tenant sont le bon choix. Les files partagées avec limitation de débit semblent simples au départ, mais finissent toujours par présenter des problèmes de clients bruyants (noisy neighbors). Une file isolée vous donne une véritable isolation sans la logique de priorité complexe.
Pour la mise en œuvre du jeton bucket, Redis est solide, il suffit de stocker une clé par tenant en utilisant un refill basé sur TTL. Les tentatives ne se déclenchent pas toutes en même temps après la réinitialisation de la fenêtre de limitation de débit — utilisez un backoff exponentiel avec jitter.
Quant à l’allocation des workers, envisagez un modèle en tiers : un petit pool de workers dédiés pour les tenants à haut volume, des workers partagés pour les autres. Cela évitera le surprovisionnement tout en protégeant le débit des meilleurs tenants.
Ce qui est souvent négligé, c’est d’instrumenter la profondeur et le temps d’attente de la file d’attente par tenant, pas seulement les dépassements de limite de débit. C’est là que vous localiserez généralement le vrai goulot d’étranglement avant qu’il y ait un problème de SLA.
Quels types d’API externes frappez-vous ? Certaines ont des allocations de rafales qui peuvent considérablement adoucir le problème des tentatives.
Un token bucket par tenant dans Redis est le bon instinct, et le choix de conception clé est d’appliquer la limite avant que le job n’atteigne le worker, et non à l’intérieur. Si le worker extrait un job et attend ensuite un rate limit, vous bloquez la capacité du worker sans rien faire, ce qui est exactement votre problème de « un tenant occupé mange la capacité de tout le monde ».
La structure est donc : webhook vers la queue, puis une gate qui vérifie le bucket du tenant dans Redis et ne libère le job au worker que lorsque ce tenant a du budget, sinon elle le remet en queue avec un délai. Cela empêche le backlog d’un tenant limité de bloquer les autres.
Sur les rafales de retry : vos retries ont aussi besoin d’un backoff par tenant, pas d’un backoff global, sinon un tenant qui est déjà à sa limite refait un retry sur le même mur et amplifie la rafale. Exponential backoff avec jitter, comptabilisé dans le même bucket.
Pour une vraie équité avec des centaines de tenants, des queues séparées pour vos quelques tenants à plus gros volume et une queue partagée pour la long tail est généralement la division pragmatique. L’isolation complète par queue est plus propre mais bien plus à exploiter. Un dernier point : mettez une vérification sur la profondeur par queue par tenant afin que quand l’une commence à s’accumuler au-delà d’un seuil, vous le découvriez tôt, au lieu de le découvrir quand ce tenant se plaint que ses jobs ont des heures de retard.