Rate limits
Política de control de tasa de uso de la API pública y del relay SMTP.
Estado actual
| Tipo de límite | Estado | Donde se enforce |
|---|---|---|
| Requests/segundo por API key | Planeado | — |
| Requests/segundo por tenant (agregado) | Planeado | — |
| Mensajes/segundo SMTP por credencial | Planeado | — |
Para bandwidth shaping (activo):
- El cap se mide en bytes-on-wire estimados:
len(EML) × num_recipientspor send. - HTTP: cuando se excede, la API responde
429 Too Many Requestscon headerRetry-After(segundos). Un único request que supere la capacity total del burst devuelve413 Payload Too Largepermanente. - SMTP: cuando se excede, el relay responde
452 4.3.1 Instance bandwidth limit exceeded, retry in <seg>senEND-OF-MESSAGE. La MTA emisora reintentará con su propia política de backoff. - El cap por instance y su
burst_secondsse configuran a nivel infra (no son negociables por contrato hoy). Subida del límite por necesidad operativa o comercial: contactar soporte.
Los otros límites (req/s por API key, etc.) siguen siendo planeados, no implementados. Los integradores deben diseñar clientes asumiendo que van a existir (ver valores y headers abajo).
Scope diseñado
Los límites se aplican en dos planos:
-
API pública (envío y consultas):
- Por API key: requests/segundo individualmente por credencial.
- Por tenant: suma agregada de todas las API keys del tenant.
- Por endpoint: límites específicos en endpoints caros (exports, búsquedas amplias).
-
SMTP relay (API pública → relay SMTP):
- Por credencial SMTP: mensajes/segundo enviables vía SASL PLAIN.
- Por tenant: agregado SMTP.
Los valores por defecto y por plan se acuerdan con comercial. Referencia tentativa:
| Plan | Requests API/s | Envíos SMTP/s |
|---|---|---|
| Starter | 10 | 20 |
| Standard | 50 | 100 |
| Enterprise | Custom | Custom |
Headers y respuesta 429
Cuando el rate limit esté implementado, las respuestas HTTP incluirán:
| Header | Significado |
|---|---|
X-RateLimit-Limit | Cupo total en la ventana actual |
X-RateLimit-Remaining | Requests restantes en la ventana |
X-RateLimit-Reset | Timestamp Unix cuando se resetea la ventana |
Retry-After | Segundos hasta el próximo request permitido (solo en 429) |
Respuesta al exceder el límite — mismo envelope RFC 9457 application/problem+json que usan las tres APIs para todo error (ver Respuestas de error):
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 50
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1713531000
Retry-After: 12
Content-Type: application/problem+json
{
"type": "https://docs.fidelizador.com/errors/rate-limit-exceeded",
"title": "Too Many Requests",
"status": 429,
"detail": "API rate limit exceeded. Retry after 12s.",
"code": "rate_limit_exceeded",
"trace_id": "019c9633-1d8f-7624-8394-17db17f86867"
}
El trace_id en el body permite correlacionar con logs en caso de soporte. El X-Request-Id de la respuesta (nunca en el body — ver) también sirve para correlación por request individual.
Estrategias de backoff recomendadas
Para el cliente que consume la API:
- Exponential backoff con jitter: empezar con el
Retry-Afterrecibido; si vuelve a fallar, duplicar con jitter aleatorio (±20%) para evitar thundering herd. - Circuit breaker: si más del 50% de las últimas 20 requests son 429, pausar todo el envío por ~30s.
- Bucket preventivo: mantener un token bucket local del lado del cliente usando
X-RateLimit-Remainingpara evitar alcanzar el límite en primer lugar. - Distribución temporal: para campañas masivas, espaciar el envío en ventanas (ejemplo: 1000 correos/minuto en vez de 60000 de golpe).
Cómo se implementará
Diseño técnico (planeado, sujeto a cambio):
- Contadores en memoria compartida: ventanas deslizantes de conteo con expiración automática.
- Enforcement en la API pública: middleware que consulta el contador antes de procesar la ruta. Ante 429, short-circuit sin tocar la base de datos.
- Enforcement SMTP: en el relay antes de
DATA, con un código transitorio + mensaje de retry. Esto es rate-limiting (frecuencia), distinto de la cuota mensual de envío - esa ya está activa y usa sus propios códigos (452 4.7.1por sobrepaso,550 5.7.1sin suscripción activa,451 4.3.0si la fuente no responde): ver. - Configuración: por credencial y a nivel tenant.
Seguimiento de la implementación: issue interno (por crear).