Comment implémenter la gestion de quotas LLM dans un SaaS multitenant : architecture, code et facturation
26/06/2026
Comment implémenter la gestion de quotas LLM dans un SaaS multitenant
Intention : montrer pas à pas comment concevoir et implémenter une gestion de quotas et d’attribution de coûts pour les appels à des modèles LLM (Large Language Models) dans une application SaaS multitenant. Public : CTO / lead dev qui doivent garantir contrôle des coûts, isolation tenant et piste d’audit.
Pourquoi c’est critique pour un SaaS qui utilise des LLM
- Les appels LLM coûtent de l’argent à l’usage ; sans quota, un tenant peut exploser votre facture.
- Il faut tracer l’usage pour la facturation, le debugging et la conformité.
- Les limites doivent être appliquées en temps réel (UX) sans tuer la latence.
Vue d’ensemble de l’architecture
Composants clés :
- API gateway / middleware tenant-aware qui authentifie et identifie le tenant.
- Module de contrôle de quotas (en mémoire distribuée comme Redis ou token bucket service).
- Circuit vers le provider LLM avec pooling, batching et backoff.
- Pipeline d’enrichissement pour facturation : logs agrégés vers Postgres / Data Warehouse.
- Tableau de bord et alerting (prometheus + grafana ou équivalent).
Schéma simplifié
Client → API Gateway (tenant id) → Quota check (Redis) → Broker LLM → Provider LLM → Response
Étape 1 — modèle de données minimal (facturation & quotas)
Exemple PostgreSQL (simplifié) :
CREATE TABLE tenants (
id uuid PRIMARY KEY,
name text,
plan text,
llm_monthly_quota_tokens bigint DEFAULT 0, -- quota en tokens ou en crédits
llm_rate_limit_per_minute int DEFAULT 60
);
CREATE TABLE llm_usage (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id uuid REFERENCES tenants(id),
timestamp timestamptz NOT NULL DEFAULT now(),
tokens_used bigint,
cost_cents bigint,
request_id text
);
Remarque : vous pouvez stocker quota en « tokens », en « requêtes » ou en « crédits monétaires » selon votre modèle commercial.
Étape 2 — enforcement en temps réel (exemple Node.js + Redis)
Principe : utiliser un compteur atomique par fenêtre (sliding window ou token bucket). Exemple simplifié avec Redis INCR et TTL pour une fenêtre par minute.
const express = require('express');
const Redis = require('ioredis');
const redis = new Redis();
const app = express();
async function checkQuota(tenantId, tokensNeeded = 1) {
const key = `quota:${tenantId}:${new Date().toISOString().slice(0,16)}`; // YYYY-MM-DDTHH:MM
const current = await redis.incrby(key, tokensNeeded);
// set TTL la première fois
await redis.expire(key, 70); // ~70s pour une fenêtre minute
// récupérer quota du tenant depuis la DB (cache possible)
const tenantQuotaPerMinute = await getTenantRateLimit(tenantId); // implémenter
return current <= tenantQuotaPerMinute;
}
app.post('/api/ai', async (req, res) => {
const tenantId = req.headers['x-tenant-id'];
const tokensEstimate = estimateTokens(req.body.prompt);
const ok = await checkQuota(tenantId, tokensEstimate);
if (!ok) return res.status(429).json({error: 'quota exceeded'});
// forward to broker LLM...
});
Tips :
- Pour précision, utilisez token bucket pour permettre rafales (burst) contrôlées.
- Mettez en cache la configuration par tenant (Redis ou in-memory) pour éviter un hit BDD à chaque requête.
- Estimez les tokens côté serveur avant appel LLM (ex : tokenizer simple) pour débiter correctement.
Étape 3 — broker LLM : optimisation coût / latence
Le broker est responsable de :
- Grouper les requêtes lorsque possible (batching).
- Réessayer avec backoff en cas d’erreur transitoire.
- Appliquer un circuit breaker si un provider LLM rate limit ou a une erreur.
- Remplacer les appels directs par un système de priorisation si les quotas sont proches de l’épuisement.
// pseudo : vérifier réponse provider et journaliser usage
const result = await callProviderLLM(payload);
await recordUsage({tenantId, tokensUsed: result.tokens, costCents: computeCost(result.tokens)});
Étape 4 — attribution de coût et export pour facturation
Calculez coût = tokens_used * price_per_token du provider + marge. Stocker une ligne llm_usage par requête permet :
- Une facturation précise par cycle de facturation.
- La possibilité d'alerter le client quand il approche du quota.
- Audits et analyses de coût par feature.
Exemple d’agrégation simple (Postgres)
SELECT tenant_id, sum(tokens_used) as tokens, sum(cost_cents) as cost
FROM llm_usage
WHERE timestamp >= '2026-06-01' AND timestamp < '2026-07-01'
GROUP BY tenant_id;
Remarque : n’inventez pas les prix du provider dans votre UI ; récupérez-les via configuration ou API provider.
Erreurs fréquentes et comment les éviter
- Débiter après l’appel LLM : si l’appel échoue, vous avez un désaccord. Solution : réserver (optimiste) puis confirmer/ajuster après réponse.
- Ne pas tenir compte des tokens de la réponse : la consommation inclut prompt + completion.
- Utiliser une fenêtre fixe simple sans token bucket : mène à des effets de pile au début de chaque fenêtre.
- Stocker tous les logs synchrones en base de données : impacte la latence. Utiliser un buffer asynchrone (queue) pour l’insertion en masse.
Métriques à monitorer
- Requests/min par tenant
- Tokens consommés par minute / tenant
- Coût estimé / jour / tenant
- Taux 429 (quota exceeded)
- Latency 95e centile pour appels LLM
Sécurité et conformité
Quelques recommandations pratiques :
- Chiffrer les clés provider LLM en vault et limiter leur exposition aux seuls services nécessaires.
- Isoler les logs sensibles (PII) et appliquer masking avant stockage.
- Auditer les accès à la configuration des quotas (RBAC).
Exemples d’extensions avancées
- Quota dynamique : ajuster automatiquement les limites selon usage historique et risque financier.
- Modèles hybrides : basculer certaines requêtes vers un modèle open source local pour réduire coûts.
- Plans multi-métriques : combiner quotas en tokens + nombre de créations de contenu + coût monétaire.
Checklist d’implémentation rapide
- Définir l’unité de quota (tokens, requêtes, crédits).
- Centraliser l’identification tenant (API gateway).
- Implémenter enforcement en Redis (token bucket ou sliding window).
- Créer pipeline asynchrone pour journaliser usage et coûts.
- Ajouter alerting et tableau de bord par tenant.
- Tester en charge et simuler dépassements de quota.
Snippet réponse rapide (AEO)
Pour contrôler les coûts LLM dans un SaaS multitenant, identifiez le tenant en entrée, estimez les tokens, appliquez un token bucket atomique (Redis) pour l’enforcement en temps réel, puis journalisez usage + coût de façon asynchrone pour la facturation.
Ressources internes utiles
Pour aller plus loin en architecture SaaS et intégration IA, consultez nos pages sur les services SaaS et l’intelligence artificielle.
- Novane — services SaaS
- Novane — intégration intelligence artificielle
- Novane — Node.js (exemples et bonnes pratiques pour broker)
Conclusion : implémenter une gestion de quotas LLM solide demande trois choses : identification tenant fiable, enforcement atomique et journalisation asynchrone pour la facturation. Commencez par un prototype (Redis + broker) puis industrialisez (monitoring, plans dynamiques, backoff).
Besoin d’un audit ou d’un prototype pour votre application ? Contactez-nous pour une séance de consulting.

