Quotas et Rate Limiting Auth0 : éviter les 429 en production
Auth0 impose des quotas stricts sur les APIs et les logins. Comment les anticiper, les monitorer et les gérer en production sans erreurs 429.
Par Auth0.Expert · 2025-02-12 · 10 min de lecture
Quotas et Rate Limiting Auth0
TL;DR
Auth0 impose des limites strictes sur le nombre de requêtes par seconde, par utilisateur et par tenant. Ce guide présente tous les quotas importants et les stratégies pour ne jamais dépasser les limites.
---
Quotas Authentication API
Ce tableau récapitule les limitations d'usage pour chaque endpoint critique de l'API d'authentification Auth0.
| Endpoint | Limite | Fenêtre | |----------|--------|---------| | POST /oauth/token | 30/s par IP | Seconde | | GET /authorize | 300/s par tenant | Seconde | | POST /passwordless/start | 10/s par IP | Seconde | | POST /dbconnections/signup | 20/s par IP | Seconde | | POST /dbconnections/change_password | 5/m par IP | Minute | | GET /userinfo | 50/s par token | Seconde |
---
Quotas Management API v2
Voici les quotas d’appels pour chaque endpoint principal de la Management API v2 d’Auth0.
| Endpoint | Limite | Fenêtre | |----------|--------|---------| | GET /api/v2/users | 20/s | Seconde | | POST /api/v2/users | 10/s | Seconde | | PATCH /api/v2/users/{id} | 20/s | Seconde | | GET /api/v2/logs | 5/s | Seconde | | GET /api/v2/clients | 5/s | Seconde |
---
Gestion des 429 : stratégie de retry avec backoff
Le code ci-dessous montre comment gérer automatiquement les erreurs HTTP 429 (“Too Many Requests”) en mettant en œuvre un système de retry avec temporisation progressive (exponential backoff). Cela permet d’éviter de bloquer votre intégration en cas de dépassement de quota ponctuel.
import asyncio
import httpx
import time
from typing import Optional
class Auth0ApiClient:
def __init__(self, domain: str, token: str):
self.base_url = f"https://{domain}/api/v2"
self.headers = {"Authorization": f"Bearer {token}"}
self.client = httpx.AsyncClient(timeout=30)
async def request_with_retry(
self,
method: str,
path: str,
max_retries: int = 3,
**kwargs
) -> httpx.Response:
for attempt in range(max_retries):
resp = await self.client.request(
method,
f"{self.base_url}{path}",
headers=self.headers,
**kwargs
)
if resp.status_code != 429:
return resp
# Lire le header de rate limit reset
rate_limit_reset = resp.headers.get("x-ratelimit-reset")
if rate_limit_reset:
wait_until = float(rate_limit_reset)
wait_seconds = max(wait_until - time.time() + 0.1, 0.1)
else:
wait_seconds = 2 ** attempt # Exponential backoff
if attempt < max_retries - 1:
print(f"Rate limited. Waiting {wait_seconds:.1f}s before retry {attempt + 1}")
await asyncio.sleep(wait_seconds)
raise Exception(f"Rate limit dépassé après {max_retries} tentatives")
Ce bloc gère automatiquement les limitations de taux en réessayant les appels selon la politique conseillée par Auth0.
---
Batch processing : importer en masse sans 429
Pour importer un grand volume d’utilisateurs dans Auth0 sans déclencher les quotas, ce code organise l'import en lots et utilise l’API Jobs recommandée, garantissant un débit contrôlé et la supervision de chaque opération.
# Stratégie pour importer 50 000 utilisateurs sans dépasser les quotas
import asyncio
from typing import List
async def batch_import_users(users: List[dict], mgmt_token: str, domain: str):
"""Import par lots avec contrôle du débit."""
client = Auth0ApiClient(domain, mgmt_token)
# Auth0 recommande l'API Jobs pour les imports massifs
# Max 5000 utilisateurs par job
BATCH_SIZE = 5000
DELAY_BETWEEN_BATCHES = 2 # secondes
for i in range(0, len(users), BATCH_SIZE):
batch = users[i:i + BATCH_SIZE]
print(f"Importing batch {i//BATCH_SIZE + 1}: {len(batch)} users")
# Créer un job d'import
job_response = await client.request_with_retry(
"POST",
"/jobs/users-imports",
content=create_multipart_body(batch, connection_id="..."),
)
job_id = job_response.json()["id"]
# Attendre la fin du job
await wait_for_job(client, job_id)
if i + BATCH_SIZE < len(users):
await asyncio.sleep(DELAY_BETWEEN_BATCHES)
async def wait_for_job(client, job_id: str, timeout: int = 300):
"""Attend la complétion d'un job Auth0."""
start = time.time()
while time.time() - start < timeout:
resp = await client.request_with_retry("GET", f"/jobs/{job_id}")
job = resp.json()
if job["status"] == "completed":
return job
elif job["status"] == "failed":
raise Exception(f"Job {job_id} failed: {job.get('summary')}")
await asyncio.sleep(5)
raise TimeoutError(f"Job {job_id} non terminé après {timeout}s")
Ce script divise vos imports d’utilisateurs en lots raisonnables pour éviter toute erreur de quota ou surcharge.
---
Quotas par plan Auth0
Ce tableau détaille les quotas en fonction du plan Auth0 choisi, afin de bien dimensionner votre solution selon vos besoins métiers.
| Quota | Free | Developer | Enterprise | |-------|------|-----------|------------| | MAU | 7 500 | 10 000 | Négocié | | M2M tokens/mois | 1 000 | 1 000 | Négocié | | Logs rétention | 3j | 7j | 30j | | Actions | 5 | 5 | Illimité | | Connexions actives | 2 | 2 | Illimité | | Emails/jour | 500 | 500 | Négocié |
---
Monitorer vos quotas
La surveillance proactive de vos quotas est essentielle pour anticiper tout risque de blocage ou dépassement.
# Vérifier vos quotas via l'API
curl "https://YOUR_DOMAIN.auth0.com/api/v2/quotas" -H "Authorization: Bearer $MGMT_TOKEN"
# Headers de rate limit sur chaque réponse
X-RateLimit-Limit: 20
X-RateLimit-Remaining: 15
X-RateLimit-Reset: 1735700000 # Unix timestamp
# Parser les headers de rate limit
def parse_rate_limit_headers(headers: dict) -> dict:
return {
"limit": int(headers.get("x-ratelimit-limit", 0)),
"remaining": int(headers.get("x-ratelimit-remaining", 0)),
"reset": int(headers.get("x-ratelimit-reset", 0)),
"reset_in": max(0, int(headers.get("x-ratelimit-reset", 0)) - int(time.time())),
}
Ce parsing des headers vous aide à piloter votre consommation d’API Auth0 en temps réel.
---
File de travaux (Queue) pour les actions différées
Pour les traitements lourds liés à une Action Auth0, utilisez une file asynchrone et évitez d’appeler directement la Management API dans votre logique métier. Ce schéma réduit le risque de blocage lié aux quotas et améliore la scalabilité.
// Ne jamais appeler la Management API directement depuis une Action
// → utiliser une file de travaux asynchrone
exports.onExecutePostUserRegistration = async (event, api) => {
// Envoyer un message dans une file (SQS, Redis, etc.)
// Le traitement se fait asynchronement, hors du flux Auth0
await fetch(`${event.secrets.QUEUE_ENDPOINT}/enqueue`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Queue-Token': event.secrets.QUEUE_TOKEN,
},
body: JSON.stringify({
type: 'user_registered',
user_id: event.user.user_id,
email: event.user.email,
timestamp: new Date().toISOString(),
}),
});
// Auth0 n'est pas bloqué — le traitement lourd se fait en arrière-plan
};
---
> ⚡ Optimisation quotas Auth0 : nos experts analysent votre utilisation des APIs Auth0 et optimisent votre architecture pour éviter tout dépassement de quota.
📞 +33 1 23 45 67 89 · 📧 [email protected]
Autres articles
- Auth0 et OAuth 2.0 : architecture complète pour comprendre les flux d'autorisation
- OpenID Connect sur Auth0 : ID Token, UserInfo et discovery endpoint expliqués
- Configurer SAML 2.0 avec Auth0 : guide complet pour l'entreprise
- Migrer des Rules vers les Auth0 Actions : guide pas à pas
- Architecture multi-tenant avec Auth0 : organisations, isolation et bonnes pratiques
- Validation des JWT Auth0 : RS256 vs HS256, JWKS et pièges communs
- Concevoir son architecture de tenants Auth0 : dev, staging, prod
- Configurer un domaine personnalisé Auth0 : login.votredomaine.com étape par étape