¿Cómo se escribe un post-mortem que sirve? Anatomía de un incident report blameless
Todo el mundo publica "cómo saqué 100 en Lighthouse". Casi nadie publica un post-mortem. Y sin embargo, nada comunica madurez operativa como un incident report bien escrito: muestra que operaste algo bajo presión, que entendiste por qué falló y que cambiaste el sistema para que no vuelva a pasar. Este post es la plantilla que uso para escribirlos —blameless, accionable, citable— con un ejemplo ilustrativo para que veas cada parte funcionando.
Un post-mortem no es un acta de culpa. Es un cambio de diseño documentado: el sistema falló, entendimos por qué, y lo dejamos imposible de fallar igual.
¿Qué quiere decir "blameless"?
Blameless significa que el post-mortem ataca al sistema, no a la persona. "Fulano borró la tabla" no es una causa raíz; es el final de una cadena de causas: ¿por qué un comando manual podía borrar producción?, ¿por qué no había confirmación?, ¿por qué la alerta llegó tarde? La regla práctica: cada vez que aparezca un nombre propio como causa, seguí preguntando "por qué" hasta llegar a una decisión de diseño que se pueda cambiar. La cultura blameless no es ser amable — es que la gente reporte la verdad sin miedo, que es la única forma de aprender del incidente.
La estructura, parte por parte
Un post-mortem que sirve tiene siempre las mismas secciones. Las escaneables, con subtítulos tipo pregunta, porque también se leen rápido en una crisis:
- Resumen — qué pasó, en dos líneas, arriba de todo.
- Impacto — a cuántos usuarios/requests afectó y por cuánto tiempo. Números, no adjetivos.
- Detección — qué alerta saltó y cuánto tardó. Si nadie la detectó hasta que se quejó un cliente, eso ya es un hallazgo.
- Timeline — minuto a minuto, en una zona horaria fija, desde la primera señal hasta la resolución.
- Root cause — la causa de diseño, no el síntoma.
- Fix inmediato — qué paró el sangrado.
- Fix permanente — qué cambia para que no se repita.
- Action items — cada uno con responsable y fecha. Sin esto, el post-mortem es un diario, no una mejora.
Un ejemplo ilustrativo
Nota: el incidente de abajo es un ejemplo construido para mostrar el formato, no un evento real. ¿Querés ver el método aplicado a un incidente real? Está el post-mortem de cómo un
next buildme tiró abajo el preview de este sitio.
Resumen. Durante 23 minutos, el ~8% de los requests al endpoint de checkout devolvieron 503. Causa raíz: un cambio de configuración bajó el límite de conexiones del pool de la base de datos por debajo del pico de tráfico real.
Impacto. ~8% de los checkouts entre 14:02 y 14:25 (UTC). Error rate del endpoint: 0.3% → 8.1%. Sin pérdida de datos.
Detección. La alerta de error rate (>2% por 2 min) saltó a las 14:04, 2 minutos después del despliegue. Buena detección; el problema fue el tiempo de diagnóstico.
Timeline (UTC).
- 14:02 — Deploy que incluía, sin que nadie lo notara, un cambio de
max_connections. - 14:04 — Alerta de error rate. On-call reconoce.
- 14:12 — Se descarta causa de aplicación; se mira la base de datos.
- 14:18 — Se identifica el cambio de config en el diff del deploy.
- 14:22 — Rollback iniciado.
- 14:25 — Error rate normalizado.
Root cause. No fue "alguien cambió un número". Fue que un parámetro de capacidad podía cambiarse sin un check que lo validara contra el tráfico real, y que el diagnóstico tardó porque la métrica de saturación del pool no estaba en el dashboard de primera línea.
Fix inmediato. Rollback del deploy.
Fix permanente.
- Validación en CI que bloquea bajar
max_connectionspor debajo del pico p99 de los últimos 30 días. - Métrica de saturación del pool agregada al dashboard de on-call.
Action items.
- Check de capacidad en CI — responsable: infra, fecha: +1 semana.
- Saturación de pool en el dashboard principal — responsable: infra, fecha: +3 días.
- Runbook de "503 en checkout" — responsable: on-call lead, fecha: +1 semana.
El error más común: parar en el síntoma
El 90% de los post-mortems flojos terminan en "se desplegó un mal cambio, tengan más cuidado". Eso no es una causa raíz, es un deseo. La pregunta correcta no es "¿quién se equivocó?" sino "¿por qué el sistema permitió que un error individual escalara a un incidente?". La respuesta casi siempre es un control que faltaba — y ese control es el verdadero entregable del post-mortem.
Por qué esto es trabajo de growth
Un caído de 23 minutos en checkout no es solo un SLA roto: es conversión que no ocurrió, carritos abandonados, confianza erosionada. Downtime es revenue perdido medido en otra unidad. Por eso la reliability no es un costo que compite con el crecimiento; es infraestructura del crecimiento. La misma cabeza que instrumenta un funnel para entender dónde se cae una conversión instrumenta un sistema para entender dónde se cae un request. Es el mismo rigor, dos superficies.
¿Querés que tu operación esté preparada para responder así cuando algo falle —y que falle menos? Es parte de lo que reviso en un Growth Audit. Hablemos.