Playbook de Guardias e Incidentes (On-Call)
Playbook práctico para ingenieros on-call: triage, escalamiento, comunicación y postmortems. Reduce el MTTR y construye una cultura de respuesta a incidentes resiliente.
Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.
Playbook de Guardias e Incidentes (On-Call)
Introducción
Los incidentes son inevitables. Lo que separa a los equipos resilientes de los frágiles no es la ausencia de fallos, sino la velocidad y calidad de su respuesta. Este playbook proporciona un enfoque estructurado para manejar incidentes en producción — desde la primera alerta hasta el postmortem.
Ciclo de Vida de la Respuesta a Incidentes
Detectar → Triage → Mitigar → Resolver → Postmortem
↑ │
└────────── Monitorear y Comunicar ─────────┘
1. Detección
Principios de Alertamiento
| Alerta | Por Qué Importa | Umbral |
|---|---|---|
| Pico de tasa de error | Los usuarios ven fallos | > 0.1% de requests por 2 minutos |
| Latencia p99 | Experiencia de usuario degradada | > 500ms por 5 minutos |
| Saturación | Agotamiento de recursos acercándose | CPU > 80%, memoria > 85%, disco > 90% |
| Falla de dependencia | Servicio downstream caído | Health check falla 3 veces |
La Fatiga de Alertas Es Real
Si una alerta suena y el ingeniero on-call no toma acción, no es una alerta — es ruido. Elimina o degrada alertas con tasa de falsos positivos > 80%.
2. Triage
Checklist del Primer Minuto
Cuando te paginan, responde estas preguntas en orden:
- ¿Qué está fallando? — nombre del servicio, endpoint, región
- ¿Quién se ve afectado? — todos los usuarios, un subconjunto, solo internos?
- ¿Cuándo empezó? — hora exacta del primer fallo (revisa logs de deploy)
- ¿Qué cambió? — algún deploy, cambio de config o shift de dependencia?
- ¿Está empeorando? — tendencia de tasa de error en el tiempo
Niveles de Severidad
| Severidad | Definición | Tiempo de Respuesta | Ejemplo |
|---|---|---|---|
| SEV-1 | Outage completo o pérdida de datos | 15 minutos | Sistema de pagos caído para todos |
| SEV-2 | Funcionalidad mayor degradada | 30 minutos | Búsqueda devuelve vacío para 50% |
| SEV-3 | Impacto menor o workaround existe | 2 horas | Dashboard admin lento, API rápido |
| SEV-4 | Sin impacto a usuarios, riesgo potencial | Próximo día hábil | Pico de logs, sin errores aún |
3. Mitigación
Detén la Sangría Primero
Tu primer objetivo no es arreglar la causa raíz — es restaurar el servicio. Prefiere rollback sobre forward-fix durante un incidente.
# Rollback de un deploy malo
kubectl rollout undo deployment/api-service
# Activar un kill switch de feature flag
curl -X POST "https://config-service/flags/checkout-v2" \
-d '{"enabled": false}'
# Escalar horizontalmente para absorber carga
kubectl scale deployment/api-service --replicas=20
Tácticas Comunes de Mitigación
| Problema | Mitigación Rápida |
|---|---|
| Deploy malo | Rollback a última versión buena |
| Pico de tráfico | Escalar horizontalmente, activar rate limiting |
| Falla de dependencia | Activar circuit breaker, servir cache viejo |
| Sobrecarga de base de datos | Matar queries lentas, agregar réplicas de lectura |
| Error de configuración | Revertir config, reiniciar con valores previos |
4. Comunicación
Actualizaciones de Estado Internas
Publica en tu canal de incidentes cada 10 minutos:
[SEV-2] Latencia de checkout elevada
- Inicio: 14:32 UTC
- Impacto: ~30% de requests de checkout timeout
- Causa: pool de conexiones a base de datos agotado tras deploy v2.4.1
- Mitigación: rollback a v2.4.0 a las 14:45, monitoreando recuperación
- ETA: 15:00 UTC si la tendencia se mantiene
- Comandante: @alice
Comunicación Externa
| Severidad | ¿Notificar Externamente? | Quién |
|---|---|---|
| SEV-1 | Sí, inmediato | Soporte + página de estado |
| SEV-2 | Sí, si > 30 min | Soporte + página de estado |
| SEV-3 | No, a menos que pregunte | Solo interno |
| SEV-4 | No | Solo interno |
Reglas de Comunicación Sin Culpa
- No nombres individuos como causas
- No uses “error humano” como causa raíz
- Enfócate en qué pasó, qué se hizo, y qué sigue
5. Resolución
Definición de Resuelto
Un incidente se considera resuelto cuando:
- Las tasas de error vuelven a línea base por 10 minutos
- Todas las mitigaciones son estables
- No aparecen nuevos síntomas
- El comandante de incidente declara “todo claro”
Después del Todo Claro
- Detén el reloj (registra duración total del incidente)
- Agenda postmortem dentro de 24 horas para SEV-1/2
- Crea tickets de seguimiento con dueños y fechas límite. Actualiza CI/CD si es necesario.
- Actualiza runbooks con lo aprendido
6. Postmortem
Los Cinco Por Qué
Pregunta “por qué” recursivamente hasta llegar a un problema sistémico, no a un síntoma.
Problema: La API de pagos devolvió 500 por 20 minutos.
¿Por qué? → El pool de conexiones a base de datos se agotó.
¿Por qué? → v2.4.1 aumentó el pool por defecto pero olvidó cerrar conexiones en retry.
¿Por qué? → El cambio no fue probado bajo carga.
¿Por qué? → Los tests de carga no cubren el flujo de checkout.
¿Por qué? → Los escenarios de carga no se actualizaron en 6 meses.
Acción: Agregar flujo de checkout a [tests de carga](/recipes/performance/load-testing-k6) semanales; requerir pase de carga en [CI](/guides/devops/cicd-pipeline-guide).
Plantilla de Postmortem
# Postmortem: [Nombre del Incidente] ([SEV-X])
## Resumen
- Fecha: 2024-06-12
- Duración: 23 minutos
- Impacto: 12% de intentos de checkout fallidos
## Línea de Tiempo
- 14:32 — Primera alerta: spike de tasa de error en /api/checkout
- 14:35 — On-call reconoció
- 14:40 — Identificado agotamiento de pool de conexiones
- 14:45 — Rollback a v2.4.0
- 14:55 — Tasas de error volvieron a línea base
## Causa Raíz
v2.4.1 introdujo un loop de retry que filtraba conexiones a base de datos.
## Lo Que Salió Bien
- Rollback completado en menos de 5 minutos
- El monitoreo apuntó claramente al agotamiento del pool
## Lo Que Salió Mal
- Los tests de carga no cubrían la nueva lógica de retry
- No había detección de filtrado de conexiones en staging
## Acciones
| Acción | Dueño | Fecha Límite |
|--------|-------|-------------|
| Agregar flujo de checkout a tests de carga | @bob | 2024-06-19 |
| Agregar alerta de filtrado de conexiones | @alice | 2024-06-15 |
Lo que funciona
- Rota on-call de forma justa — nadie debería estar on-call más de 1 semana en 4
- Compensa por horas extras — paga extra o da tiempo libre compensatorio
- Shadow on-call — nuevos ingenieros hacen shadow por 2-4 semanas antes de recibir el pager
- Automatiza runbooks — si un paso del runbook es manual, agrégalo al backlog de automatización
- Revisa alertas trimestralmente — elimina ruido, ajusta umbrales, arregla alertas intermitentes
Errores Comunes
- Saltarse postmortems porque “estamos muy ocupados”
- Culpar individuos en lugar de arreglar sistemas
- Forward-fixear durante un incidente en lugar de hacer rollback
- Comunicar demasiado tarde a clientes
- No tener on-call secundario para escalamiento
- Mantener la misma persona on-call por semanas
Preguntas Frecuentes
¿Qué pasa si no sé cómo arreglar el problema?
Esperado. Tu trabajo es contener el impacto y encontrar a la persona correcta — no saber cada sistema. Escalá temprano y claramente. Una escalación de 5 minutos es mejor que 30 minutos solo.
¿Cómo balanceo respuesta a incidentes con trabajo de funcionalidades?
Los incidentes son trabajo no planificado. Rastrealos. Si un equipo gasta > 20% de capacidad de sprint en incidentes, es una señal de invertir en confiabilidad (tests, automatización, refactor) en lugar de nuevas capacidades.
¿Deberían los ingenieros juniors estar on-call?
Sí, con mentoría. Hacer shadow de ingenieros senior durante incidentes es una de las formas más rápidas de aprender cómo fallan los sistemas. Empieza con rotaciones de baja severidad y páralos con un senior el primer mes.
Temas Avanzados
Escenario: Response a Incidente Sev-1 en E-commerce
Incidente: Checkout caido, 100% usuarios afectados
Severidad: Sev-1 (critico)
Inicio: 14:12 UTC
On-call: Maria (primary), Carlos (secondary)
Timeline de respuesta:
14:12 - Alerta dispara: CheckoutErrorRate 100%
14:13 - Maria recibe page (PagerDuty)
14:14 - Maria abre Slack #incident-checkout
14:15 - Maria verifica: error 500 en todos los requests
14:16 - Declara Sev-1, abre bridge (Zoom)
14:17 - Invita a Carlos (secondary), team lead, DBA
14:18 - Maria investiga: deploy reciente?
kubectl rollout history deploy/checkout
-> Deploy v2.4 hace 8 min
14:20 - Carlos verifica DB: conexiones saturadas
-> Pool de conexiones agotado
14:22 - Maria decide rollback a v2.3
14:23 - Rollback ejecutado: kubectl rollout undo
14:26 - Servicio restaurado, errores a 0%
14:30 - Maria confirma estabilidad por 5 min
14:35 - Cierra bridge, declara resuelto
14:36 - Crea ticket para post-mortem (48h)
Roles durante el incidente:
| Rol | Persona | Responsabilidad |
|-----|---------|----------------|
| Incident Commander | Maria | Coordinar, decidir |
| Communications | Carlos | Actualizar stakeholders |
| Subject Matter Expert | DBA | Investigar DB |
| Scribe | Bot automatico | Timeline en Slack |
Comunicaciones:
14:15 - Slack #status: "Investigando Sev-1 checkout"
14:20 - Slack #status: "Causa identificada: deploy v2.4"
14:22 - Slack #status: "Ejecutando rollback"
14:26 - Slack #status: "Servicio restaurado"
14:35 - Slack #status: "Incidente resuelto, post-mortem pendiente"
Post-mortem (48h):
- Resumen: Checkout caido 14 min por deploy defectuoso
- Impacto: $28K ventas perdidas, 8K usuarios afectados
- Causa raiz: Query N+1 introducida en v2.4, no detectada por tests
- 5 Whys:
1. Por que cayo? Pool de conexiones agotado
2. Por que se agoto? Query N+1 abrio 1000 conexiones
3. Por que no se detecto? Tests no cubrian concurrency
4. Por que no habia tests? No habia integration test de DB
5. Por que? CI no requería integration tests
- Acciones:
1. Agregar integration test de DB en CI (owner: team, 1 sem)
2. Agregar check de N+1 en CI (owner: platform, 2 sem)
3. Bajar pool max connections (owner: SRE, 3 dias)
4. Agregar alerta de pool saturation (owner: SRE, 3 dias)
Lecciones:
- El Incident Commander coordina, no investiga
- Comunicar temprano y frecuentemente
- Rollback es la primera opcion, no la ultima
- Post-mortem blameless: arreglar el sistema, no culpar
- Cada accion tiene owner y fecha
Como preparo a un equipo nuevo para on-call?
Comienza con shadowing: el nuevo ingeniero acompana al on-call durante 2 semanas sin responder pages. Luego responde pages de baja severidad con el senior como backup. Despues de 1 mes, toma turnos completos con el senior disponible. Provee un runbook por servicio. Haz game days en staging para practicar respuesta a incidentes.
Recursos Relacionados
Docker for Developers — A Complete Guide
Learn Docker from the ground up: images, containers, Dockerfiles, networks, volumes, and Docker Compose for local development.
GuideWeb Application Security (OWASP Top 10)
A developer-focused guide to the OWASP Top 10: injection, broken access control, XSS, insecure design, and how to prevent each vulnerability with code examples.
GuideTechnical Documentation Strategy: Docs as Code
A practical guide to treating documentation as code: versioning, review workflows, structure, and tools that keep docs accurate, discoverable, and maintainable.
DocBug Report Template
A structured bug report template to help teams reproduce, triage, and resolve defects faster with clear reproduction steps and expected behavior.
DocService Level Objective (SLO) Document Template
An SLO document template that defines reliability targets, error budgets, and escalation policies for services and platforms.
GuideMonitoring and Alerting — Metrics, Logs, and Dashboards
A practical guide to observability: the three pillars (metrics, logs, traces), RED and USE methods, alert design, and building dashboards that actually help.