Limitación SMTP: Demuestra que es el proveedor y adáptate sin fricciones

¿Te fue útil?

Tu equipo de producto lo llama “el correo va lento”. Soporte lo llama “los clientes no reciben enlaces de restablecimiento”.
Tú lo llamas “la cola está echando raíces”. En algún punto entre tu MTA y el borde del proveedor,
el SMTP saliente empieza a devolver educados códigos 4xx y tus tiempos de entrega pasan de segundos a horas.

La parte difícil no es arreglar la limitación. La parte difícil es probar dónde está, para que no “optimices” el sistema equivocado,
quemes reputación o generes una tormenta de reintentos que convierta un incidente pequeño en una revisión profesional toda la noche.

Cómo se ve realmente la limitación SMTP (en registros de producción)

La limitación SMTP es el proveedor diciéndote: “Ahora no”. Normalmente llega como fallos transitorios (4xx),
a veces con códigos de estado extendidos (como 4.7.0), otras veces con un texto que parece redactado por un abogado.
Tu MTA hace lo que hacen los MTAs: encola y reintenta. Si no controlas la forma de los reintentos, no controlas el incidente.

Las señales clásicas:

  • 421 al conectar o tras el saludo: “Servicio no disponible”, a menudo con “intenta más tarde”.
  • 451/452 durante la transacción: “Fallo temporal local” o “almacenamiento insuficiente” (a veces mentira, a veces no).
  • 4.7.x estados extendidos: “mensaje diferido”, “limitado por tasa”, “throttling temporal”, “demasiadas conexiones”.
  • Desvíos de conexión: “conexión perdida”, “timeout”, “el host dijo: 421 …”
  • Ráfagas por destinatario: solo algunos dominios de destino se ralentizan, otros vuelan.

Aquí está lo que la gente pasa por alto: la limitación no es solo “demasiados mensajes”. También son demasiadas conexiones simultáneas,
demasiados destinatarios por mensaje, demasiados fallos, patrones sospechosos o un problema de reputación que se disfraza de “capacidad”.
Los proveedores raramente admiten qué perilla tocaste. Simplemente te dan un 4xx y esperan que te comportes.

Datos interesantes y contexto histórico (el correo siempre ha sido así)

  • SMTP es más antiguo que la mayoría de tus herramientas. Viene de principios de los 80, diseñado para redes cooperativas, no para economías adversarias de spam.
  • Los diferimientos 4xx son una característica, no un error. “Intenta más tarde” se pensó para suavizar cortes. Ahora también suaviza la aplicación de políticas.
  • Los códigos de estado extendidos (linaje RFC 3463) se introdujeron porque el 4xx/5xx simple era demasiado vago para operaciones modernas.
  • El greylisting popularizó la idea del fallo temporal intencional. Algunos receptores devolvían 4xx en el primer contacto para disuadir spambots que no reintentan.
  • Los grandes proveedores movieron las metas de reputación a comportamiento. Los patrones de volumen, tasas de queja, autenticación y engagement ahora influyen en throttling.
  • Las políticas por dominio se endurecieron a medida que creció el abuso entrante. Limitar conexiones por IP remitente se volvió normal cuando los botnets aprendieron paralelismo.
  • La separación bulk vs transaccional se volvió una pauta operativa. No por estética—mezclarlos empeora ambos durante eventos de limitación.
  • DNS y timeouts son parte de los síntomas de “throttling”. Cuando un proveedor está sobrecargado, a menudo ves TLS más lento y demoras en el banner antes del 4xx explícito.

Una cita que deberías pegar en tu monitor:

“La esperanza no es una estrategia.” — Gene Kranz

Guion rápido de diagnóstico (primeras/segundas/terceras comprobaciones)

El objetivo es simple: encontrar el cuello de botella en menos de 15 minutos. No “entenderlo todo”.
Solo identificar si el punto de estrangulamiento es tu host, tu política MTA, tu red o el proveedor de destino.

Primero: ¿es global o por dominio?

  • Si todos los destinos se ralentizan, sospecha límites locales de recursos, problemas de DNS o un upstream compartido (relay/smarthost).
  • Si solo un proveedor/dominio se ralentiza (p. ej., outlook.com o un solo MX corporativo), sospecha throttling del receptor o problemas de reputación/política.

Segundo: ¿es “no se puede conectar” o “no se puede entregar tras conectar”?

  • Retrasos en la conexión/saludo (timeouts, 421 al conectar): probable límite de conexiones, tarpitting o sobrecarga remota.
  • Diferimientos en RCPT/DATA (451/452/4.7.x tras MAIL FROM/RCPT TO/DATA): limitación por política/tasa, reputación, disparadores de contenido o problemas a nivel de destinatario.

Tercero: ¿tu forma de reintentos lo empeora?

  • Si tu cola crece y los intervalos de reintento son cortos, puedes estar generando una tormenta de reintentos que convence al proveedor de que eres un mal vecino.
  • Si la concurrencia es alta para un solo dominio, estás activando límites de conexión por dominio.
  • Si agrupas demasiados destinatarios por mensaje, un destinatario diferido puede penalizar toda la transacción.

Regla rápida: estabiliza antes de optimizar

Reduce la concurrencia, añade backoff, preserva el correo transaccional y deja de golpear al proveedor.
Puedes restaurar el rendimiento después de recuperar una cola en estado estable.

Demuestra que es el proveedor: evidencias válidas para el postmortem

“El proveedor nos está limitando” es fácil decirlo y difícil probarlo. Te preguntarán:
¿Es nuestra red? ¿Es nuestra configuración TLS? ¿Estamos sobrecargados? ¿Estamos en una lista negra? ¿Enviamos basura?
Necesitas evidencias que separen fallo local de política remota.

Cómo se ve la prueba

  • Respuestas SMTP remotas muestran lenguaje o códigos explícitos de limitación (421/451/4.7.x) después de establecer TCP/TLS con éxito.
  • Agrupamiento por destino: un proveedor difiere, otros aceptan al ritmo normal, desde el mismo host y ventana temporal.
  • Recursos locales estables: CPU, RAM, disco, red están bien mientras la cola crece—apuntando lejos de saturación local.
  • Firmas de límite de conexiones: “demasiadas conexiones”, reinicios frecuentes durante el saludo o banners retrasados solo para ciertos MX hosts.
  • Correlación con cambios de patrón de envío: salió un lanzamiento, campaña de marketing, pico de restablecimientos o un incidente que causó reintentos.

Qué NO cuenta como prueba

  • “No cambiamos nada.” (Probablemente sí cambiaste. O el proveedor cambió. O tu tráfico cambió.)
  • “La cola es grande.” (Las colas crecen por docenas de razones.)
  • “El proveedor siempre es inestable.” (Verdad en espíritu, inútil en un postmortem.)

Broma #1: SMTP es el único protocolo que puede decirte educadamente “vuelve después” mientras arruina tu tarde.

Tareas prácticas: comandos, significado de salidas, decisiones (12+)

Las tareas abajo asumen un host Linux corriendo Postfix. Si usas Exim, Sendmail o un relay gestionado,
la filosofía sigue aplicando: recoge evidencias sólidas y luego moldea el tráfico para no pelear con el receptor.

Tarea 1: Contar mensajes diferidos e identificar destinos principales

cr0x@server:~$ postqueue -p | awk '
/^[A-F0-9]/ {id=$1}
/@/ && /to=</ {for (i=1;i<=NF;i++) if ($i ~ /to=</) {addr=$i; gsub(/.*to=<|>.*/,"",addr); split(addr,a,"@"); dom=a[2]; print dom}}
/status=deferred/ {deferred=1}
' | sort | uniq -c | sort -nr | head
  913 outlook.com
  402 protection.outlook.com
  177 gmail.com
   61 yahoo.com
   44 example-corp.com

Qué significa: Los diferimientos se agrupan por dominio de destino; ese es tu primer discriminador “proveedor vs local”.
Si un dominio domina, sospecha limitación remota o política.

Decisión: Aplica límites de concurrencia/ritmo por dominio para los dominios dominantes y protege las rutas de correo transaccional.

Tarea 2: Extraer respuestas SMTP remotas para entregas diferidas

cr0x@server:~$ sudo grep -E "status=deferred" /var/log/mail.log | tail -n 5
Jan 04 10:12:21 mx1 postfix/smtp[22119]: 3F2C41A2B: to=<user1@outlook.com>, relay=outlook-com.olc.protection.outlook.com[104.47.56.36]:25, delay=182, delays=0.2/0/12/170, dsn=4.7.0, status=deferred (host outlook-com.olc.protection.outlook.com[104.47.56.36] said: 451 4.7.500 Server busy. Please try again later. (S3150) (in reply to MAIL FROM command))
Jan 04 10:12:22 mx1 postfix/smtp[22121]: 7B9DF1A31: to=<user2@outlook.com>, relay=outlook-com.olc.protection.outlook.com[104.47.56.38]:25, delay=164, delays=0.1/0/10/154, dsn=4.7.0, status=deferred (host outlook-com.olc.protection.outlook.com[104.47.56.38] said: 451 4.7.500 Server busy. Please try again later. (S3150) (in reply to RCPT TO command))
Jan 04 10:12:24 mx1 postfix/smtp[22118]: 9C1C11A40: to=<user3@gmail.com>, relay=gmail-smtp-in.l.google.com[142.250.102.26]:25, delay=1.2, delays=0.1/0/0.2/0.9, dsn=2.0.0, status=sent (250 2.0.0 OK  1704363144 x7si123456qka.321 - gsmtp)
Jan 04 10:12:25 mx1 postfix/smtp[22125]: 1A7D21A55: to=<user4@example-corp.com>, relay=mx.example-corp.com[203.0.113.10]:25, delay=0.8, delays=0.1/0/0.2/0.5, dsn=2.0.0, status=sent (250 2.0.0 queued as 8F2A9C)
Jan 04 10:12:27 mx1 postfix/smtp[22130]: 5E0B71A66: to=<user5@outlook.com>, relay=outlook-com.olc.protection.outlook.com[104.47.56.37]:25, delay=211, delays=0.2/0/9/201, dsn=4.7.0, status=deferred (host outlook-com.olc.protection.outlook.com[104.47.56.37] said: 421 4.7.0 Temporary server error. Please try again later. (in reply to end of DATA command))

Qué significa: Tienes entregas exitosas a otros dominios mientras un proveedor específico devuelve “Server busy” y códigos 4.7.x.
Eso es casi evidencia de calidad judicial: el par remoto está difiriendo explícitamente.

Decisión: Trátalo como limitación del proveedor. Reduce el paralelismo hacia ese proveedor y aumenta el backoff; no “aceleres reintentos”.

Tarea 3: Ver si estás saturando procesos cliente SMTP localmente

cr0x@server:~$ sudo postconf -n | egrep "default_process_limit|max_use|smtp_destination_concurrency_limit|smtp_destination_rate_delay|smtp_connect_timeout"
default_process_limit = 200
max_use = 100
smtp_destination_concurrency_limit = 50
smtp_destination_rate_delay = 0s
smtp_connect_timeout = 30s

Qué significa: Alta concurrencia y delay de tasa cero pueden parecer una avalancha de conexiones para un proveedor.
Puedes estar activando límites por IP o por tenant.

Decisión: Limita la concurrencia por destino e introduce un pequeño rate delay. Mantén límites globales razonables.

Tarea 4: Medir conexiones SMTP activas hacia el proveedor

cr0x@server:~$ sudo ss -tnp | awk '$4 ~ /:25$/ || $4 ~ /:587$/ {print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head
  62 104.47.56.36
  59 104.47.56.38
  57 104.47.56.37
  12 142.250.102.26
   4 203.0.113.10

Qué significa: Mantienes muchas conexiones concurrentes hacia el proveedor que está limitando.
Incluso si cada mensaje es pequeño, la concurrencia de conexión por sí sola puede activar throttling.

Decisión: Reduce la concurrencia por destino. Revisa también si las respuestas remotas lentas hacen que tu cliente mantenga sockets abiertos más tiempo.

Tarea 5: Comprobar retrasos en el saludo (tarpitting) durante el handshake SMTP

cr0x@server:~$ time bash -c 'echo | nc -w 10 outlook-com.olc.protection.outlook.com 25'
220 DM6PR10CA0001.outlook.office365.com Microsoft ESMTP MAIL Service ready at Thu, 4 Jan 2026 10:13:12 +0000

real	0m6.412s
user	0m0.002s
sys	0m0.002s

Qué significa: Un banner de 6 segundos no es “latencia normal de internet”. Es carga, tarpitting o ritmo deliberado.
Si este retraso es solo para un proveedor, estás viendo conformado por el remoto.

Decisión: Baja la concurrencia aún más; los largos retrasos de saludo multiplican tu conteo efectivo de conexiones y amplifican el crecimiento de la cola.

Tarea 6: Validar velocidad y corrección de resolución DNS para el MX objetivo

cr0x@server:~$ dig +tries=1 +time=2 MX outlook.com
;; ANSWER SECTION:
outlook.com.		1800	IN	MX	5 outlook-com.olc.protection.outlook.com.

;; Query time: 21 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Thu Jan  4 10:13:20 UTC 2026
;; MSG SIZE  rcvd: 98

Qué significa: DNS es rápido y sensato. Si el tiempo de consulta es de cientos/miles de ms o se agota, puedes maldiagnosticar throttling.

Decisión: Si DNS es lento, arregla los resolvers primero. No ajustes Postfix por una caída de DNS.

Tarea 7: Comprobar salud del host local (disco e I/O) para no culpar al proveedor por tu propio desastre

cr0x@server:~$ df -h /var/spool/postfix
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme0n1p2  200G   48G  143G  26% /
cr0x@server:~$ iostat -xz 1 3
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          3.20    0.00    1.10    0.30    0.00   95.40

Device            r/s     w/s   rkB/s   wkB/s  aqu-sz  await  %util
nvme0n1          12.0    21.0   540.0  1120.0    0.02   0.7    2.1

Qué significa: Mucho espacio; sin cuello de I/O. El crecimiento de la cola no se debe a que tu spool sea lento o esté lleno.

Decisión: Sigue buscando río arriba. Si el disco está lleno o el I/O al máximo, arréglalo primero—el correo es brutalmente sensible al comportamiento de fsync.

Tarea 8: Comprobar si el gestor de colas está saturado

cr0x@server:~$ mailq | head -n 20
-Queue ID-  --Size-- ----Arrival Time---- -Sender/Recipient-------
3F2C41A2B      5120 Thu Jan  4 09:58:11  noreply@service.example
                                         user1@outlook.com
                                         (host outlook-com.olc.protection.outlook.com[104.47.56.36] said: 451 4.7.500 Server busy. Please try again later. (S3150) (in reply to MAIL FROM command))

7B9DF1A31      4891 Thu Jan  4 10:01:03  noreply@service.example
                                         user2@outlook.com
                                         (host outlook-com.olc.protection.outlook.com[104.47.56.38] said: 451 4.7.500 Server busy. Please try again later. (S3150) (in reply to RCPT TO command))

Qué significa: Los diferimientos están anotados con las respuestas remotas. Puedes mostrar esto a cualquiera.

Decisión: Si el mismo diferimiento se repite para un dominio, deja de golpear. Ajusta límites por dominio y los intervalos de reintento.

Tarea 9: Confirmar que no estás detrás de un smarthost o cuello de botella de relay

cr0x@server:~$ sudo postconf -n | egrep "^relayhost|^smtp_sasl_auth_enable|^smtp_tls_security_level"
relayhost =
smtp_sasl_auth_enable = no
smtp_tls_security_level = dane

Qué significa: No hay relayhost configurado; entregas directas a MX hosts. Bien: el análisis por dominio tiene sentido.
Si relayhost está establecido, tu cuello de botella podría ser tu proveedor de relay, no el dominio destino.

Decisión: Si usas un relayhost, traslada el diagnóstico al límite del relay: sus respuestas, tus límites de auth, sus cuotas.

Tarea 10: Rastrear un intento de entrega único de extremo a extremo con logging SMTP verboso

cr0x@server:~$ sudo postconf -e "debug_peer_list = outlook-com.olc.protection.outlook.com"
cr0x@server:~$ sudo systemctl reload postfix
cr0x@server:~$ sudo grep -E "outlook-com\.olc\.protection\.outlook\.com|postfix/smtp" /var/log/mail.log | tail -n 20
Jan 04 10:14:10 mx1 postfix/smtp[22301]: connect to outlook-com.olc.protection.outlook.com[104.47.56.36]:25: Connected
Jan 04 10:14:16 mx1 postfix/smtp[22301]: << 220 DM6PR10CA0001.outlook.office365.com Microsoft ESMTP MAIL Service ready
Jan 04 10:14:16 mx1 postfix/smtp[22301]: >> EHLO mx1.service.example
Jan 04 10:14:17 mx1 postfix/smtp[22301]: << 250-DM6PR10CA0001.outlook.office365.com Hello [198.51.100.10]
Jan 04 10:14:17 mx1 postfix/smtp[22301]: >> MAIL FROM:<noreply@service.example>
Jan 04 10:14:17 mx1 postfix/smtp[22301]: << 451 4.7.500 Server busy. Please try again later. (S3150)

Qué significa: La conexión TCP tuvo éxito. Llegó el banner. EHLO funcionó. El proveedor difirió en MAIL FROM.
Eso no es tu firewall. No es tu DNS. Es el receptor diciendo “más despacio”.

Decisión: Implementa pacing por dominio y un backoff más largo; conserva las evidencias (logs) para escalar con el proveedor.

Tarea 11: Verificar postura de autenticación (SPF/DKIM/DMARC) desde tu dominio remitente

cr0x@server:~$ dig +short TXT service.example
"v=spf1 ip4:198.51.100.10 -all"
"google-site-verification=..."
cr0x@server:~$ dig +short TXT selector1._domainkey.service.example
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..."
cr0x@server:~$ dig +short TXT _dmarc.service.example
"v=DMARC1; p=quarantine; rua=mailto:dmarc@service.example"

Qué significa: Autenticación ausente o descuidada no siempre provoca bounce duro; puede aumentar la presión de filtrado y throttling.
Los proveedores pueden aceptar más lentamente mientras deciden si eres de confianza.

Decisión: Si la autenticación falta/está rota, arréglalo antes de negociar “límites”. No puedes ajustar tu camino fuera de la desconfianza.

Tarea 12: Inspeccionar disparadores de composición de mensaje (tamaño, número de destinatarios y batching)

cr0x@server:~$ sudo postcat -q 3F2C41A2B | egrep -i "^(message_size|recipient_count|sender|original_recipient|message_arrival_time)"
message_size:            5120
recipient_count:         15
sender:                  noreply@service.example
message_arrival_time:    Thu Jan  4 09:58:11 2026

Qué significa: Una sola entrada en cola tiene 15 destinatarios. Algunos proveedores penalizan un gran fanout de destinatarios,
y un destinatario diferido puede retrasar la entrega de todo el sobre (dependiendo de cómo agrupe tu app).

Decisión: Si haces batching pesado de destinatarios, reduce los destinatarios por mensaje para los dominios con throttling. Más entradas en cola, menos bloqueos por multi-destinatario.

Tarea 13: Comprobar si la negociación TLS está atascándose o fallando (a menudo se interpreta mal como throttling)

cr0x@server:~$ openssl s_client -starttls smtp -connect outlook-com.olc.protection.outlook.com:25 -servername outlook-com.olc.protection.outlook.com -brief </dev/null
CONNECTION ESTABLISHED
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer certificate: CN=*.protection.outlook.com
Verification: OK

Qué significa: TLS está bien. Si esto falla o se cuelga, podrías estar tratando con middleboxes, problemas de MTU o carga TLS del proveedor.

Decisión: Si TLS es el cuello, ajusta timeouts e investiga la ruta de red. No solo reduzcas la tasa y llames a eso solucionado.

Tarea 14: Confirmar que tu firewall/NAT no está descartando conexiones salientes bajo carga

cr0x@server:~$ sudo conntrack -S | head
entries  32768
searched 154832
found    98211
new      2211
invalid  0
ignore   0
delete   2179
delete_list 2179

Qué significa: Si invalid es alto, o la tabla conntrack está cerca de su capacidad, verás timeouts SMTP y reinicios aleatorios
que parecen throttling. El proveedor recibe la culpa; tu caja NAT está ardiendo en silencio.

Decisión: Si conntrack está saturado, reduce el churn de conexiones salientes (baja concurrencia, aumenta reutilización) y aumenta la capacidad de conntrack donde corresponda.

Adáptate sin fricciones: límites, backoff, concurrencia y limpieza de colas

Una vez que estás seguro de que es limitación upstream, tienes dos objetivos:
entregar lo que puedas sin enfadar más al proveedor y mantener tus sistemas estables mientras el backlog se drena.
Esto es retropresión, no una carrera.

Principio 1: Separa las clases de correo (lo transaccional tiene prioridad)

Si mezclas restablecimientos de contraseña con boletines en la misma cola, te mereces el incidente que estás a punto de tener.
El correo transaccional tiene un usuario esperando al otro lado. El correo bulk tiene un calendario de marketing.
Eso no es igual a ojos del responsable del incidente.

Hazlo en la capa de aplicación (flujos separados) o en el MTA (transportes separados), pero hazlo.
En Postfix, normalmente eso significa rutas dedicadas en transport_maps y diferentes ajustes de concurrencia.

Principio 2: Límites por dominio superan a límites globales

Los topes globales son instrumentos toscos: te protegen, pero castigan dominios que aceptarían correo rápido.
Los proveedores aplican throttling por IP remitente, por tenant, por remitente, por destino y por heurística conductual.
Tu mejor coincidencia es la concurrencia y el pacing por dominio.

Principio 3: El backoff debe ser exponencial con jitter y lo suficientemente largo para importar

Los MTAs ya reintentan, pero los valores por defecto pueden ser erróneos para el throttling moderno. Si reintentas demasiado rápido, pareces un botnet.
Si reintentas demasiado lento, el correo transaccional pierde su ventana de utilidad.
El truco es aplicar comportamientos de reintento diferentes para distintas clases y destinos.

Patrones concretos de ajuste para Postfix

Puedes hacer esto de forma limpia sin convertir tu MTA en un snowflake afinado a mano.
Empieza con concurrencia por dominio y un pequeño rate delay.

cr0x@server:~$ sudo postconf -e "smtp_destination_concurrency_limit = 10"
cr0x@server:~$ sudo postconf -e "smtp_destination_rate_delay = 1s"
cr0x@server:~$ sudo postconf -e "default_destination_concurrency_limit = 20"
cr0x@server:~$ sudo systemctl reload postfix

Qué significa: Limitas las entregas concurrentes por destino y añades un espaciado mínimo entre entregas.
Esto reduce las avalanchas de conexiones y suaviza el tráfico.

Decisión: Si el proveedor devuelve explícitamente “demasiadas conexiones” o “server busy”, esta es tu primera palanca.

Para destinos particularmente sensibles, define un transporte dedicado con límites más estrictos.

cr0x@server:~$ sudo tee -a /etc/postfix/master.cf >/dev/null <<'EOF'
slowoutlook unix  -       -       n       -       -       smtp
  -o smtp_destination_concurrency_limit=2
  -o smtp_destination_rate_delay=3s
  -o smtp_connect_timeout=20s
EOF
cr0x@server:~$ sudo tee /etc/postfix/transport >/dev/null <<'EOF'
outlook.com slowoutlook:
protection.outlook.com slowoutlook:
EOF
cr0x@server:~$ sudo postmap /etc/postfix/transport
cr0x@server:~$ sudo postconf -e "transport_maps = hash:/etc/postfix/transport"
cr0x@server:~$ sudo systemctl reload postfix

Qué significa: Solo el correo a esos dominios usa el transporte limitado; otros dominios mantienen el rendimiento normal.

Decisión: Usa transportes dedicados cuando un proveedor es el problema y no quieres una desaceleración global.

Control de reintentos: no dejes que “diferido” se convierta en “DDoS con mejor gramática”

El timing de reintentos de Postfix lo controlan parámetros del gestor de colas. Puedes ajustarlos, pero hazlo con cuidado:
afinar reintentos afecta a cada mensaje, incluidos los que habrían funcionado rápido.
Prefiere primero pacing y concurrencia por dominio.

cr0x@server:~$ sudo postconf -n | egrep "minimal_backoff_time|maximal_backoff_time|maximal_queue_lifetime"
minimal_backoff_time = 300s
maximal_backoff_time = 4000s
maximal_queue_lifetime = 5d

Qué significa: Tu MTA no martillará cada minuto; retrocede hasta alrededor de una hora máximo entre intentos.
Si tu backoff mínimo es demasiado pequeño, puedes auto-amplificar la limitación.

Decisión: Si ves diferimientos repetidos rápidos, sube minimal_backoff_time de forma moderada, pero no destroces la latencia transaccional para todos los dominios.

Higiene de colas: protege el sistema de la propia cola

Una cola creciente no es solo “mensajes esperando”. Es uso de disco, presión de inodos y CPU gastada en escanear colas.
Tu objetivo es mantener el MTA reactivo incluso mientras está retrasado.

  • Mantén /var/spool/postfix en almacenamiento rápido y monitoriza uso de inodos.
  • Evita enormes ráfagas de una sola cola controlando la tasa de envío desde la aplicación upstream.
  • Prefiere menos clientes SMTP simultáneos hacia un proveedor en lugar de abrir constantemente nuevas conexiones.

Broma #2: Si te quedas mirando mail.log suficiente tiempo, empieza a mirarte de vuelta—y siempre quiere más disco.

Tres mini-historias corporativas desde las minas del correo

Mini-historia 1: El incidente causado por una suposición equivocada

Una SaaS mediana operaba su propio Postfix para correo transaccional. Añadieron una nueva región y empezaron a enviar desde un bloque de IPs fresco.
El despliegue fue bien una semana, luego los restablecimientos de contraseña empezaron a llegar 30–90 minutos tarde para usuarios en un proveedor importante.
El ingeniero on-call vio una cola grande y asumió que el host Postfix estaba infradimensionado. Doblaron CPU y añadieron memoria.

La cola siguió creciendo. Escalaron la instancia otra vez. Seguía creciendo. Ajustaron límites de descriptores de archivos y luego reiniciaron Postfix en hora punta,
lo que brevemente no mejoró nada y arruinó permanentemente la confianza de todos. Mientras tanto, las entregas a Gmail seguían casi instantáneas,
lo que debería haber sido una pista pero se ignoró porque “la cola es grande”.

El verdadero problema estaba en los logs: repetidos 451 4.7.500 Server busy en MAIL FROM, solo para los MX de ese proveedor.
Estaban activando límites de conexión porque la app había pasado recientemente de enviar un correo por evento a agrupar
y ejecutar múltiples workers paralelos por cliente. Más eventos significaron más clientes SMTP simultáneos.

Una vez que restringieron la concurrencia por dominio a 2 y añadieron un rate delay, el backlog se drenó en unas horas.
El postmortem tuvo una línea brutal: “Escalamos lo equivocado porque no segmentamos por dominio de destino.”
La lección no fue “compra servidores más grandes.” La lección fue: prueba dónde está el cuello de botella antes de tocar hardware.

Mini-historia 2: La optimización que salió mal

Una gran empresa quiso reducir la sobrecarga SMTP. Alguien propuso “maximizar la reutilización de conexiones” y “mayor concurrencia”
para obtener mejor rendimiento a receptores externos. En papel, se veía genial: menos handshakes TLS por mensaje, más entregas en paralelo,
colas más cortas. El cambio se desplegó gradualmente. Las métricas mejoraron. Todos se felicitaron.

Entonces una campaña de marketing colisionó con un incidente no relacionado que causó un pico en tráfico de restablecimientos.
El MTA hizo exactamente lo que se había afinado: abrió y mantuvo muchas sesiones concurrentes hacia un puñado de grandes proveedores.
Esos proveedores interpretaron el comportamiento como agresivo y empezaron a tarpittear durante el saludo SMTP
y a diferir en RCPT y DATA con códigos 4.7.x.

La “optimización” creó un bucle de retroalimentación desagradable. Los largos retrasos en el saludo significaron conexiones mantenidas más tiempo.
Conexiones mantenidas significaron menos ranuras disponibles. Menos ranuras significaron mensajes más en cola.
Mensajes en cola se reintentaron. Mensajes reintentados abrieron más conexiones. Ya te haces la idea.
La cola se volvió no lineal. No porque el servidor fuera lento, sino porque el remoto lo ralentizó y el MTA no se adaptó.

La solución no fue revertir todo el tuning. Fue añadir controles por dominio y una política:
el correo bulk y el transaccional no deben compartir la misma clase de concurrencia, y ningún proveedor recibe paralelismo ilimitado.
También añadieron un “botón matar campaña” en la capa de aplicación. Esta es la parte poco estética:
a veces el mejor ajuste SMTP es un interruptor que detiene tu propio tráfico.

Mini-historia 3: La práctica aburrida pero correcta que salvó el día

Una organización con gestión de cambios estricta hacía salir correo por una capa de relay dedicada.
Los hosts relay no eran potentes. No eran sofisticados. Pero estaban instrumentados:
contadores por dominio de diferidos, dashboards de profundidad de cola y muestreo de logs eran parte de la configuración estándar.
Cada clase de dominio tenía un límite de concurrencia documentado y una justificación.

Una tarde, un proveedor importante empezó a devolver fallos transitorios y banners lentos. La cola comenzó a subir.
El on-call siguió el runbook: confirmar agrupamiento por dominio, confirmar diferimientos 4.7.x remotos, confirmar recursos locales estables.
El dashboard mostró que solo ese proveedor tenía diferimientos en aumento; otros dominios estaban bien.

Cambiaron el transporte para el proveedor a una “vía lenta” ya presente en la gestión de configuración.
La concurrencia bajó. El rate delay aumentó. El crecimiento de la cola se estabilizó en minutos.
El correo transaccional a otros proveedores continuó normalmente, y el backlog se drenó cuando el proveedor se recuperó.

Sin heroísmos. Sin cambios aleatorios de parámetros. Sin reinicios en pánico. La práctica aburrida fue simplemente:
predefinir comportamiento de limitación por destino y desplegar observabilidad con el MTA.
Así es como vuelves a dormir.

Errores comunes: síntoma → causa raíz → solución

Estos son los modos de fallo que siguen apareciendo porque a los humanos les encantan las historias simples.
SMTP no recompensa las historias simples.

1) Síntoma: “El correo se retrasa para todos” (pero solo un proveedor está realmente diferido)

Causa raíz: Estás aplicando un throttle global o el gestor de colas pasa la mayoría del tiempo en un solo dominio diferido.

Solución: Implementa transportes por dominio o límites de concurrencia por dominio. Mantén los dominios rápidos rápidos.

2) Síntoma: Muchos timeouts y errores “lost connection”

Causa raíz: O tarpitting/retrasos en saludo remoto, o agotamiento local de conntrack/NAT por churn de conexiones.

Solución: Mide tiempos de saludo, revisa estadísticas de conntrack y reduce la concurrencia de conexiones. Prefiere sesiones más estables y menos frecuentes.

3) Síntoma: Ves 451/4.7.x y alguien sugiere “reintentar más rápido”

Causa raíz: Malentendido de los diferimientos. Reintentos más rápidos pueden aumentar el throttling y alargar la recuperación.

Solución: Backoff con jitter. Baja la concurrencia por dominio. Estabiliza primero; drena después.

4) Síntoma: Solo los mensajes grandes se retrasan o difieren

Causa raíz: Límites de tamaño del proveedor, carga de escaneo de contenido o tu propia red/ruta TLS luchando con transferencias mayores.

Solución: Confirma las respuestas remotas (a menudo mencionan el tamaño), reduce tamaños de adjuntos y considera canales alternativos para contenido pesado.

5) Síntoma: Gmail está bien, Microsoft va lento (o viceversa)

Causa raíz: Políticas diferentes por proveedor, modelos de reputación distintos, límites de conexión distintos.

Solución: Ajusta por proveedor. No generalices desde el comportamiento de un dominio a “SMTP” en su conjunto.

6) Síntoma: La cola crece tras un release, pero los logs muestran “server busy” del proveedor

Causa raíz: El release cambió el patrón de envío (rafagas, paralelismo, batching) más que el volumen bruto.

Solución: Añade limitación upstream en la app; suaviza las ráfagas. Mantén los controles MTA como segunda línea de defensa.

7) Síntoma: Los proveedores difieren en MAIL FROM y sospechas un bug en tu MTA

Causa raíz: Decisión de política en el receptor basada en identidad/remitente/IP; MAIL FROM es un punto conveniente para cortar temprano.

Solución: Mejora autenticación (SPF/DKIM/DMARC), reduce picos y, si es necesario, “calienta” IPs en lugar de “ir a lo grande el primer día”.

Listas de verificación / plan paso a paso

Paso a paso: Diagnosticar y estabilizar en un turno de on-call

  1. Segmenta el problema por destino: identifica los dominios con más diferidos desde la cola.
  2. Lee las respuestas remotas: captura 10–20 líneas representativas de diferimiento con timestamps e IPs remotas.
  3. Confirma salud local: espacio en disco, iowait, presión de memoria, conntrack, descriptores de archivo.
  4. Mide comportamiento del handshake: retraso del banner y resultados STARTTLS para el proveedor diferido.
  5. Aprieta la concurrencia por dominio: empieza conservador (2–5) para el proveedor afectado.
  6. Añade rate delay por dominio: los segundos importan; empieza con 1–3 segundos para un proveedor problemático.
  7. Protege el correo transaccional: separa transportes o colas; prioriza resets/OTP sobre bulk.
  8. Reduce ráfagas upstream: si la app puede pausar bulk, paúsalo; si puede ralentizar, ralenticela.
  9. Mira la pendiente de la cola: estabilización significa “la cola deja de crecer”, no “la cola ha desaparecido”.
  10. Conserva evidencias: fragmentos de logs, códigos de diferimiento y series temporales. Las necesitarás para escalar con el proveedor y rendición de cuentas interna.

Checklist: Paquete de evidencias para “es el proveedor”

  • Conteo de dominios con más diferidos (desde parseo de la cola).
  • Al menos 5 líneas de log mostrando dsn=4.7.x o 421/451 con el texto SMTP del proveedor.
  • Un rastro SMTP verboso mostrando connect+EHLO exitoso seguido por diferimiento (Tarea 10).
  • Datos de timing del handshake (retraso del banner) para ese proveedor vs al menos otro proveedor.
  • Snapshots de recursos locales mostrando no saturación: disco, iostat, load, conntrack.

Checklist: Adaptación limpia (sin construir un monstruo)

  • Transporte por dominio para proveedores conocidos por limitar.
  • Valores conservadores por defecto para smtp_destination_concurrency_limit y smtp_destination_rate_delay.
  • Flujos separados para bulk y transaccional.
  • Backoff razonable; no bucles de reintento rápidos.
  • Dashboards: profundidad de cola, tasa de diferidos por dominio, percentiles de latencia de entrega.
  • Botón de apagado para correo bulk en la capa de aplicación.

Preguntas frecuentes

1) ¿Los errores 4xx siempre son throttling?

No. 4xx significa “falla temporal”, que puede incluir limitación, greylisting, mantenimiento remoto o problemas de ruteo transitorios.
El throttling es más probable cuando los 4xx se agrupan por destino e incluyen lenguaje 4.7.x como “rate limited”, “server busy” o “too many connections”.

2) ¿Cómo distingo limitación del proveedor de problemas en mi red?

Si TCP connect y EHLO tienen éxito y el receptor responde 451/421/4.7.x, es fuertemente del lado del proveedor.
Si no puedes conectar, ves muchos timeouts en muchos dominios o conntrack está saturado, tienes dolor de red local.

3) ¿Por qué la limitación a veces aparece como saludos lentos en lugar de 4xx explícitos?

El tarpitting es una táctica: retrasar el banner o las respuestas para reducir tu throughput sin gastar su propio presupuesto de políticas en rechazos explícitos.
Desde tu lado, parece “SMTP está lento”. Mide el tiempo del banner para confirmarlo.

4) ¿Debo aumentar la concurrencia de Postfix para drenar la cola más rápido?

No cuando el receptor está difiriendo. Mayor concurrencia suele aumentar la tasa de diferimientos, mantener más sockets abiertos
y ralentizar la recuperación. Cuando te limitan, drenas siendo aburrido y estable, no siendo ruidoso.

5) ¿Es mejor enviar directo a MX o a través de un servicio de relay?

Directo-a-MX te da control y visibilidad inmediata en las respuestas del receptor. Un relay puede ofrecer mejor gestión de reputación de IP,
pero también se convierte en un punto extra de estrangulamiento con sus propias cuotas y políticas. Elige uno, móntalo con instrumentación y conoce dónde está el límite.

6) ¿Una SPF/DKIM/DMARC rota puede causar throttling en vez de bounces?

Sí. Algunos proveedores degradan el comportamiento de aceptación: más diferimientos, aceptación más lenta o filtrado más severo cuando la autenticación falta o es inconsistente.
Es posible que no recibas un error claro de “auth failed”; obtienes “server busy” y un día más largo.

7) ¿Cómo mantengo rápidos los restablecimientos de contraseña durante un evento de limitación?

Separa el correo transaccional en su propio flujo y transporte, y capea agresivamente el tráfico bulk.
Considera enviar transaccional desde una identidad (dominio/subdominio/IP) calentada y estable distinta de la de marketing.

8) ¿Cuál es la forma más limpia de adaptarse sin acumular hacks permanentes?

Usa bloques de configuración pequeños y explícitos: transportes por dominio con límites documentados, además de dashboards y un runbook.
Evita ajustes globales aleatorios. Prefiere cambios reversibles con dueños claros e impacto medido.

9) ¿Cuándo debo escalar al proveedor?

Escala cuando tengas un paquete de evidencias: respuestas SMTP representativas, timestamps, IPs remitentes y prueba de que otros dominios funcionan.
Los proveedores responden mejor a datos estructurados que a “nuestros correos van lentos”.

10) ¿Puedo “probar” la limitación si el proveedor solo hace timeouts y nunca envía 4xx?

Puedes armar un caso sólido: muestra que la conexión succeedió pero el banner/comandos se estancan solo para ese proveedor,
y que el mismo host entrega normalmente a otros. No es tan limpio como un 451, pero sigue siendo evidencia accionable.

Conclusión: pasos prácticos a seguir

La limitación SMTP es normal. Pretender que no existe es cómo acabas con una cola tan grande que se convierte en un evento de negocio.
Tu trabajo es probar dónde vive la demora y luego moldear el tráfico para que el proveedor pueda aceptarlo y tus usuarios no esperen para siempre.

  • Ahora mismo: segmenta los diferidos por dominio de destino, captura respuestas remotas y confirma salud local.
  • En la hora: limita la concurrencia por dominio y añade rate delay por dominio para el proveedor afectado.
  • Antes del próximo incidente: separa flujos transaccional y bulk, añade dashboards para tasa de diferidos por dominio y habilita un kill switch.
  • Para el postmortem: conserva el paquete de evidencias. Evita que “creemos” se convierta en “adivinamos”.
← Anterior
WordPress: ‘Tiempo máximo de ejecución excedido’ — por qué ocurre y soluciones seguras
Siguiente →
Bloqueo de 2FA en Proxmox: cómo evitarlo (y cómo recuperarse rápido)

Deja un comentario