Contexto: cuando "Publicar" significa "Esperar Horas"

¡Hola Devs! Fíjate en lo que pasa cuando un creador le da clic a Publicar: se dispara una cadena de sistemas — transcodificación, análisis de contenido, priorización, entrega. Cuando esa cadena no tiene holgura, un solo pico se convierte en horas de retraso. Y lo peor: la primera señal que recibe el usuario es el silencio. 😶

Esto es un breakdown estilo postmortem de un incidente real en un pipeline de medios. El escenario: la infra de transcodificación de video llegó al tope, se formó un backlog, y episodios que normalmente publican en minutos quedaron horas en cola.

Las causas raíz no eran exóticas — eran el cuarteto clásico que todo sistema distribuido eventualmente enfrenta:

  • Headroom insuficiente para tráfico en burst
  • Un job batch programado compitiendo con trabajo en tiempo real
  • Un upgrade de calidad que subió silenciosamente el costo por ítem
  • Un bug de scheduler dejando ~10% de CPU ociosa

Si corres cualquier pipeline que ingiere contenido de usuario (podcast, video, imagen, inferencia de LLM), los modos de falla aquí te van a sonar familiares. Vamos a destriparlo. 🔍

Referencia de la fuente: write-up original del incidente

Server room racks with queue backlog dashboard overlay illustrating transcoding capacity limits Dev Environment Setup

Los Cuatro Factores que Convergieron (y Qué Enseñan)

1. Headroom no es lujo — es requisito de correctitud

El sistema escalaba bien en steady-state. Lo que no absorbía era burst de entrega masiva. Planeación de capacidad que solo modela el promedio es un plan para fallar en la cola.

Regla de bolsillo: dimensiona para pico_esperado × 1.5 como mínimo, y agrega un presupuesto separado para jobs batch.

2. Jobs batch deben ceder ante tráfico en tiempo real

Un job de reprocesamiento corría junto con la ingesta de episodios nuevos. Individualmente, todo bien. Juntos, saturaron el pool.

Esto es inversión de prioridad. El trabajo del creador en tiempo real siempre debe preemptar el trabajo de background. Un patrón simple:

# Consumidor de cola con prioridad (pseudo-código)
# Jobs de baja prioridad ceden cuando la cola en tiempo real no está vacía

PRIORIDAD_ALTA = 0  # episodios nuevos
PRIORIDAD_BAJA = 1  # reprocesamiento, backfills

def worker():
    while True:
        # Siempre drena alta prioridad primero
        job = cola.pop(PRIORIDAD_ALTA, timeout=0)
        if job is None:
            # Solo toca baja prioridad cuando tiempo real está ocioso
            job = cola.pop(PRIORIDAD_BAJA, timeout=1)
        if job:
            procesa(job)

La idea central: el trabajo de baja prioridad debe ser interrumpible, no solo "menos prioritario" en una flag del scheduler.

3. Upgrade de calidad tiene impuesto escondido de capacidad

Cambiar la transcodificación para entregar mejor calidad en bitrate menor suena a puro ganar. Pero aumentó tiempo y CPU por episodio. Si no rehaces la cuenta de capacidad después de cambiar la calidad, encogiste tu headroom sin darte cuenta.

Checklist post-cambio:

  • Re-benchmark de p50/p95/p99 por ítem
  • Recalcular tamaño de flota en pico
  • Actualizar thresholds de autoscaling

4. Bugs de scheduler son asesinos silenciosos de throughput

Después de migrar a hardware más potente, un bug de scheduling dejó ~10% de CPU ociosa. Una pérdida de 10% suena poco — hasta que ya estás al 95% de utilización y llega un pico.

Tip de observabilidad: trackea cpu_asignada / cpu_disponible como SLO de primera clase. Si divergen, tienes bug de scheduler, no problema de capacidad.

El punto ciego de 4 horas

La timeline es la parte más incómoda de la historia:

Hora (UTC)Evento
13:30Alertas iniciales disparan — no reconocidas como problema de capacidad
15:00Pico de entrega empuja transcodificación cerca del tope
16:35Job batch detenido para liberar capacidad
17:31Primer report de creador recibido
17:34Alertas automáticas confirman backlog — respuesta a incidente empieza
20:49Fix del scheduler deployado
01:02Todas las colas vaciadas

Cerca de 4 horas entre las primeras alertas y la respuesta formal. El job batch se detuvo a las 16:35, pero el alcance del problema solo se entendió a las 17:34.

Lección: alerta que dispara sin runbook es solo ruido. Toda alerta de capacidad necesita acción linkeada: "Si esto dispara, checa profundidad de cola, status del job batch, activa on-call."

Cloud infrastructure diagram showing podcast video ingestion pipeline and burst capacity scaling Technical Structure Concept

Más Allá del Fix: Construyendo un Pipeline de Publicación Resiliente

Agregar 67% más capacidad de transcodificación resuelve este incidente. No resuelve el próximo. El trabajo real es arquitectural:

Planeación de capacidad para burst, no para promedio

La planeación tradicional modela steady-state. Los pipelines modernos necesitan tres presupuestos separados:

  1. Presupuesto steady-state — tráfico diario normal
  2. Presupuesto de burst — contenido viral, uploads masivos, migraciones
  3. Presupuesto de recuperación — capacidad reservada para drenar backlogs tras incidente

Sin presupuesto de recuperación, no puedes alcanzar el ritmo después de un pico — te quedas atrás para siempre.

Backpressure en todos lados

Si tu pipeline no tiene backpressure, lo único que lo protege es la suerte. Backpressure significa:

  • Endpoints de ingesta rechazan o throttle cuando las colas downstream pasan el threshold
  • Productores reciben 429/503 explícitos con hints de retry-after
  • Clientes dejan de re-subir cuando reciben confirmación clara de "recibido y en cola"

Ese último punto importa: durante el incidente, creadores re-subieron episodios que no aparecían, aumentando la carga. El sistema falló en confirmar que el upload estaba en cola. Ingesta idempotente + acknowledgment explícito previene este efecto amplificador.

Rate limiting en cada hop

Rate limiting no es solo cosa de API gateway. Aplícalo en:

  • Endpoints de ingesta (por creador, por IP)
  • Llamadas internas servicio-a-servicio
  • Envío de jobs batch
  • Loops de retry

Observabilidad orientada al creador

Los creadores se enteraron de la caída por su audiencia antes de que la plataforma les dijera. Eso es falla de confianza, no solo técnica. Todo pipeline de publicación debería exponer:

  • Status en tiempo real: en cola / procesando / al aire
  • Tiempo estimado de publicación
  • Notificaciones proactivas en thresholds de retraso

Advertencias y limitaciones

  • Agregar capacidad es curita. Sin arreglar inversión de prioridad y backpressure, el próximo pico va a ser solo más grande.
  • "Mejor calidad en bitrate menor" no es gratis. Siempre re-benchmark después de cambios de codec/calidad.
  • Migrar a hardware más rápido puede regresar throughput si la lógica del scheduler asume topología vieja.
  • Postmortem sin action items es marketing. El reporte solo cuenta si el próximo incidente se maneja mejor.

Qué estudiar después

  • Teoría de colas: Ley de Little, colas M/M/c — por qué utilización arriba de ~80% causa latencia descontrolada.
  • Patrones de backpressure: Reactive Streams, flow control de gRPC, token buckets.
  • Colas prioritarias en la práctica: prioridades de topic en Kafka, routing de Celery, SQS + Lambda con concurrency reservada.
  • Cultura de postmortem SRE: postmortems blameless, error budgets, alertas guiadas por SLO.

Si estás construyendo cualquier cosa que ingiere contenido de usuario a escala, trata este incidente como checklist: headroom, prioridad, backpressure, observabilidad y timelines honestas. 🚀

Analytics chart of queue buildup and drain for media processing incident postmortem Programming Illustration

Conclusión

Este incidente es un ejemplo de manual de falla compuesta: ningún factor solo causaría horas de retraso, pero los cuatro juntos sí. La respuesta de ingeniería — más capacidad, fix de scheduler, alertas más tempranas — es correcta pero incompleta. El fix duradero es arquitectural: colas con prioridad, backpressure en cada hop y planes de capacidad que modelan burst y recuperación, no solo promedios.

Si tu pipeline no puede responder "qué pasa cuando llega 3x el tráfico normal en 10 minutos", no tienes un pipeline — tienes una apuesta.

Lectura relacionada

Fuente primaria: Content Ingestion & Podcast Video Incident Report

Este contenido fue redactado con la asistencia de herramientas de IA, basándose en fuentes confiables, y fue revisado por nuestro equipo editorial antes de su publicación. No reemplaza el asesoramiento de un profesional especializado.