Contexto: quando "Publicar" significa "Esperar Horas"
Olha só o que acontece quando um criador clica em Publicar: uma cadeia de sistemas dispara — transcodificação, análise de conteúdo, priorização, entrega. Quando essa cadeia não tem folga, um único pico vira horas de atraso. E o pior: o primeiro sinal que o usuário recebe é o silêncio. 😶
Este é um breakdown estilo postmortem de um incidente real em um pipeline de mídia. O cenário: a infra de transcodificação de vídeo bateu no teto, formou-se um backlog, e episódios que normalmente publicam em minutos ficaram horas na fila.
As causas raiz não eram exóticas — eram o quarteto clássico que todo sistema distribuído eventualmente encara:
- Headroom insuficiente para tráfego em burst
- Um job em lote agendado competindo com trabalho em tempo real
- Um upgrade de qualidade que aumentou silenciosamente o custo por item
- Um bug de scheduler deixando ~10% de CPU ociosa
Se você roda qualquer pipeline que ingere conteúdo de usuário (podcast, vídeo, imagem, inferência de LLM), os modos de falha aqui vão parecer familiares. Vamos destrinchar. 🔍
Referência da fonte: write-up original do incidente

Os Quatro Fatores que Convergiram (e o Que Eles Ensinam)
1. Headroom não é luxo — é requisito de correção
O sistema escalava bem em steady-state. O que ele não absorvia era burst de entrega em massa. Planejamento de capacidade que só modela a média é um plano para falhar na cauda.
Regra de bolso: dimensione para pico_esperado × 1.5 no mínimo, e adicione um orçamento separado para jobs em lote.
2. Jobs em lote precisam ceder para tráfego em tempo real
Um job de reprocessamento rodava junto com a ingestão de episódios novos. Individualmente, tudo bem. Juntos, saturaram o pool.
Isso é inversão de prioridade. Trabalho de criador em tempo real deve sempre preemptar trabalho de background. Um padrão simples:
# Consumidor de fila com prioridade (pseudo-código)
# Jobs de baixa prioridade cedem quando a fila em tempo real não está vazia
PRIORIDADE_ALTA = 0 # episódios novos
PRIORIDADE_BAIXA = 1 # reprocessamento, backfills
def worker():
while True:
# Sempre drena alta prioridade primeiro
job = fila.pop(PRIORIDADE_ALTA, timeout=0)
if job is None:
# Só toca em baixa prioridade quando tempo real está ocioso
job = fila.pop(PRIORIDADE_BAIXA, timeout=1)
if job:
processa(job)
A ideia central: trabalho de baixa prioridade deve ser interrompível, não apenas "menos prioritário" numa flag de scheduler.
3. Upgrade de qualidade tem imposto escondido de capacidade
Mudar a transcodificação para entregar melhor qualidade em bitrate menor parece ganho puro. Mas aumentou tempo e CPU por episódio. Se você não refaz a conta de capacidade depois de mudar a qualidade, você encolheu seu headroom sem perceber.
Checklist pós-mudança:
- Re-benchmark de p50/p95/p99 por item
- Recalcular tamanho de frota no pico
- Atualizar thresholds de autoscaling
4. Bugs de scheduler são assassinos silenciosos de throughput
Depois de migrar para hardware mais potente, um bug de agendamento deixou ~10% de CPU ociosa. Uma perda de 10% parece pouco — até você já estar em 95% de utilização e um pico chegar.
Dica de observabilidade: trackeie cpu_alocada / cpu_disponível como SLO de primeira classe. Se divergirem, você tem bug de scheduler, não problema de capacidade.
O ponto cego de 4 horas
A timeline é a parte mais desconfortável da história:
| Hora (UTC) | Evento |
|---|---|
| 13:30 | Alertas iniciais disparam — não reconhecidos como problema de capacidade |
| 15:00 | Pico de entrega empurra transcodificação perto do teto |
| 16:35 | Job em lote parado para liberar capacidade |
| 17:31 | Primeiro report de criador recebido |
| 17:34 | Alertas automáticos confirmam backlog — resposta a incidente começa |
| 20:49 | Fix do scheduler deployado |
| 01:02 | Todas as filas zeradas |
Cerca de 4 horas entre os primeiros alertas e a resposta formal. O job em lote foi parado às 16:35, mas o escopo do problema só foi entendido às 17:34.
Lição: alerta que dispara sem runbook é só barulho. Todo alerta de capacidade precisa de ação linkada: "Se isso disparar, checa profundidade de fila, status do job em lote, aciona on-call."

Além do Fix: Construindo um Pipeline de Publicação Resiliente
Adicionar 67% mais capacidade de transcodificação resolve este incidente. Não resolve o próximo. O trabalho real é arquitetural:
Planejamento de capacidade para burst, não para média
Planejamento tradicional modela steady-state. Pipelines modernos precisam de três orçamentos separados:
- Orçamento steady-state — tráfego diário normal
- Orçamento de burst — conteúdo viral, uploads em massa, migrações
- Orçamento de recuperação — capacidade reservada para drenar backlogs após incidente
Sem orçamento de recuperação, você não consegue alcançar o ritmo depois de um pico — você fica atrás pra sempre.
Backpressure em todo lugar
Se seu pipeline não tem backpressure, a única coisa que protege ele é sorte. Backpressure significa:
- Endpoints de ingest rejeitam ou throttle quando filas downstream passam do threshold
- Produtores recebem 429/503 explícitos com dicas de retry-after
- Clientes param de re-uploadar quando recebem confirmação clara de "recebido e enfileirado"
Esse último ponto importa: durante o incidente, criadores re-uploadaram episódios que não apareceram, aumentando a carga. O sistema falhou em confirmar que o upload estava na fila. Ingestão idempotente + acknowledgment explícito previne esse efeito amplificador.
Rate limiting em cada hop
Rate limiting não é só coisa de API gateway. Aplique em:
- Endpoints de ingest (por criador, por IP)
- Chamadas internas serviço-a-serviço
- Submissão de jobs em lote
- Loops de retry
Observabilidade voltada ao criador
Criadores souberam da queda pela audiência antes da plataforma contar. Isso é falha de confiança, não só técnica. Todo pipeline de publicação deveria expor:
- Status em tempo real: na fila / processando / no ar
- Tempo estimado de publicação
- Notificações proativas em thresholds de atraso
Avisos e limitações
- Adicionar capacidade é band-aid. Sem corrigir inversão de prioridade e backpressure, o próximo pico vai ser só maior.
- "Melhor qualidade em bitrate menor" não é de graça. Sempre re-benchmark após mudanças de codec/qualidade.
- Migrar para hardware mais rápido pode regredir throughput se a lógica de scheduler assume topologia antiga.
- Postmortem sem action items é marketing. O relatório só conta se o próximo incidente for tratado melhor.
O que estudar em seguida
- Teoria de filas: Lei de Little, filas M/M/c — por que utilização acima de ~80% causa latência descontrolada.
- Padrões de backpressure: Reactive Streams, flow control do gRPC, token buckets.
- Filas prioritárias na prática: prioridades de tópico no Kafka, routing do Celery, SQS + Lambda com concurrency reservada.
- Cultura de postmortem SRE: postmortems blameless, error budgets, alertas guiados por SLO.
Se você está construindo qualquer coisa que ingere conteúdo de usuário em escala, trate este incidente como checklist: headroom, prioridade, backpressure, observabilidade e timelines honestas. 🚀

Considerações Finais
Este incidente é um exemplo de manual de falha composta: nenhum fator sozinho causaria horas de atraso, mas os quatro juntos causaram. A resposta de engenharia — mais capacidade, fix de scheduler, alertas mais cedo — está correta, mas é incompleta. O fix durável é arquitetural: filas com prioridade, backpressure em cada hop e planos de capacidade que modelam burst e recuperação, não só médias.
Se seu pipeline não consegue responder "o que acontece quando chega 3x o tráfego normal em 10 minutos", você não tem um pipeline — tem uma aposta.
Leitura relacionada
- NVIDIA Shatters MLPerf Inference Records: Blackwell Ultra, 2.7x Software Gains, and the Rise of Interactive AI — como a infra de inferência está escalando para atender demanda em burst.
- React Compiler v1.0 Is Here: A Deep Dive into Automatic Memoization — outro caso onde "otimização automática" muda o modelo de custo, e você precisa re-medir.
Fonte primária: Content Ingestion & Podcast Video Incident Report