Una alerta indica que la latencia aumentó. El servicio sigue aceptando tráfico. El equipo abre cinco dashboards, busca ERROR en varios índices de logs y propone reiniciar dos componentes. Nadie ha definido todavía qué operación, versión, región o dependencia está afectada.
Ese patrón es común porque durante un incidente es fácil confundir actividad con progreso. Cada persona encuentra una señal distinta, cada gráfico parece importante y cada cambio promete recuperar el servicio. El riesgo es que el equipo modifique varias variables a la vez, destruya evidencia y reduzca temporalmente el síntoma sin comprender qué lo produjo.
La investigación eficaz sigue otra lógica: las métricas muestran el impacto y delimitan la población; las trazas localizan dónde se consume el tiempo o aparece el error; los logs aportan el contexto específico; el diagnóstico surge cuando esas señales se ordenan en una hipótesis que puede comprobarse o refutarse. OpenTelemetry define métricas, trazas y logs como señales distintas, mientras que la propagación de contexto permite correlacionarlas entre procesos y servicios.
Este artículo desarrolla un método operativo en siete movimientos:
- Confirmar el impacto.
- Acotar el alcance.
- Construir una línea temporal.
- Correlacionar métricas, trazas y logs.
- Formular una hipótesis verificable.
- Mitigar y comprobar la recuperación.
- Convertir lo aprendido en cambios concretos.
No es una guía de herramientas. Es una secuencia para tomar decisiones bajo presión.
Antes de investigar: proteger la operación
El objetivo inmediato de una respuesta a incidentes no es producir una explicación perfecta. Es limitar el daño de manera segura.
El orden de prioridades depende del sistema, pero normalmente debe considerar:
- Seguridad de personas y activos.
- Integridad y confidencialidad de los datos.
- Impacto real sobre usuarios y procesos críticos.
- Contención del fallo.
- Comunicación operativa.
- Preservación de evidencia suficiente para continuar el diagnóstico.
Google SRE distingue la gestión del incidente de la investigación técnica: una estructura explícita de respuesta permite coordinar acciones, comunicación y recuperación sin convertir a todos los participantes en investigadores simultáneos.
La decisión operativa puede resumirse así:
Si existe una mitigación de bajo riesgo, reversible y capaz de reducir un impacto grave, no es necesario esperar una causa raíz completa para aplicarla.
Pero la relación inversa no es válida:
Que una mitigación reduzca el impacto no demuestra que se haya identificado la causa.
Un reinicio puede liberar memoria, vaciar una cola, recrear conexiones o eliminar temporalmente una condición de bloqueo. El servicio puede mejorar y el mecanismo causal seguir intacto. Si el equipo registra “reiniciar resolvió el incidente” como causa raíz, convierte una observación temporal en una explicación no demostrada.
Decisión inicial: investigar, mitigar o hacer ambas cosas
| Condición | Decisión dominante | Precaución |
|---|---|---|
| Impacto alto y creciendo | Mitigar primero | Elegir acciones reversibles y registrar cada cambio |
| Riesgo de corrupción de datos | Contener escrituras o aislar el flujo | No priorizar disponibilidad sobre integridad sin decisión explícita |
| Impacto limitado y estable | Investigar antes de cambiar | Preservar una muestra representativa del fallo |
| Evidencia frágil o volátil | Capturar evidencia mínima | No retrasar una mitigación crítica por recopilar datos indefinidamente |
| Mitigación con alto riesgo | Validar hipótesis y blast radius | Preparar rollback y criterio de aborto |
Paso 1: detectar y confirmar el impacto
Una alerta no es todavía un incidente confirmado. Es una afirmación automatizada sobre una condición observada. Puede representar impacto real, degradación interna sin efecto visible, telemetría retrasada, un umbral mal calibrado o una población irrelevante para el servicio.
La primera obligación es convertir la alerta en una descripción operacional:
- Qué cambió.
- Desde cuándo.
- En qué población.
- Con qué magnitud.
- Qué experiencia o proceso está afectado.
- Si el comportamiento es sostenido, intermitente o ya terminó.
Empezar por Rate, Errors y Duration
Para servicios orientados a solicitudes, RED organiza el primer triage alrededor de tres señales:
- Rate: cuántas solicitudes o spans se procesan por unidad de tiempo.
- Errors: cuántas terminan en una condición considerada fallida.
- Duration: cuánto tardan, idealmente como distribución y no solo como promedio.
RED es una buena puerta de entrada, no un diagnóstico completo. Debe complementarse con saturación, colas, pools y dependencias. Google SRE resume la cobertura mínima de un sistema orientado al usuario en latencia, tráfico, errores y saturación.
No mezclar disponibilidad, éxito y latencia
Durante el incidente, estas dimensiones deben registrarse por separado:
| Dimensión | Pregunta que responde | Error de interpretación frecuente |
|---|---|---|
| Disponibilidad | ¿El servicio puede atender la operación según el SLI definido? | Asumir que aceptar TCP o responder HTTP significa que la operación está disponible |
| Éxito | ¿La operación produjo el resultado técnico y funcional esperado? | Contar todo HTTP 200 como éxito aunque el negocio rechace la transacción |
| Latencia | ¿Cuánto tardó la población medida? | Excluir timeouts o errores y mostrar solo las solicitudes rápidas que terminaron |
| Percentil | ¿Qué umbral no superó una proporción de observaciones? | Interpretar P99 como promedio o como “el 99 % más lento” |
El significado exacto depende del SLI. Una operación puede estar técnicamente disponible y funcionalmente degradada. También puede mantener una tasa de éxito aceptable mientras su cola crece y prepara el siguiente fallo.
La distribución importa porque una media puede ocultar una cola lenta. Google SRE recomienda observar percentiles para distinguir qué fracción de solicitudes está degradada, en lugar de depender solo del promedio. El cálculo y la interpretación detallada de los percentiles de latencia pertenecen al artículo especializado.
Confirmar desde más de una perspectiva
Una única fuente puede mentir por instrumentación, retraso o alcance. La confirmación debería combinar, cuando exista:
- Telemetría interna del servicio.
- Monitoreo sintético externo.
- Métricas desde el cliente o canal.
- Consumo del SLO o burn rate.
- Evidencia funcional: transacciones rechazadas, backlogs, tiempos de negocio.
La pregunta no es “¿el dashboard está rojo?”, sino:
¿Qué comportamiento del sistema o del usuario demuestra que existe una degradación y qué población la experimenta?
Paso 2: definir el alcance
“La plataforma está lenta” no es un alcance investigable.
Una descripción útil se parece a esta:
Desde las 22:14 UTC, create-order en la región south-1, versión 2026.07.12-3, presenta P99 de 2.4 segundos para payloads superiores a 250 KB; otras operaciones y la versión anterior mantienen su baseline.
Acotar reduce el número de componentes, consultas y cambios posibles. Debe segmentarse por las dimensiones que realmente pueden cambiar el comportamiento:
- Operación o endpoint.
- Servicio y dependencia.
- Región, zona o cluster.
- Versión desplegada.
- Canal o tipo de cliente.
- Tenant, producto o plan.
- Tipo y tamaño de payload.
- Método de autenticación.
- Ruta síncrona o asíncrona.
- Partición, shard o nodo.
La cardinalidad debe estar diseñada antes del incidente
No toda dimensión debe convertirse en etiqueta de métrica. Identificadores de usuario, orden o trace generan cardinalidad extrema y suelen pertenecer a logs o trazas, no a series temporales. Para métricas, las dimensiones deben permitir segmentar sin hacer inviable el backend.
OpenTelemetry usa atributos de recurso y convenciones como service.name, service.namespace y deployment.environment.name para describir de forma consistente el origen de la telemetría. Esa consistencia permite comparar señales sin traducir nombres distintos durante la crisis.
Técnica de acotación: dividir la población
Para cada hipótesis de alcance, comparar dos grupos:
- Afectado frente a no afectado.
- Versión nueva frente a anterior.
- Región degradada frente a región sana.
- Payload grande frente a pequeño.
- Cliente móvil frente a web.
- Dependencia A frente a dependencia B.
La comparación es más útil que observar un grupo aislado porque revela qué dimensión explica la diferencia.
Paso 3: construir una línea temporal
La línea temporal no es un documento administrativo para completar después. Es una herramienta de diagnóstico durante el incidente.
Debe registrar cuatro tipos de información:
- Eventos observados: alertas, cambios de métricas, errores, saturación.
- Cambios del sistema: despliegues, configuración, rotaciones de credenciales, fallos de dependencia.
- Decisiones: qué se decidió y bajo qué evidencia.
- Resultados: qué cambió después de cada acción.
| Hora UTC | Evento | Evidencia | Decisión o resultado |
|---|---|---|---|
| 22:14 | P99 de create-order supera 2 s | Histograma HTTP, región south-1 | Se abre incidente |
| 22:17 | Crece pool.pending_requests | Métrica de pool | Acotar por versión y nodo |
| 22:21 | Se confirma el salto de retries (de 4.4/s a 88/s), iniciado hacia 22:13 | Contador de intentos | Hipótesis de amplificación |
| 22:26 | Se limita concurrencia interna | Cambio reversible | Wait time empieza a caer |
| 22:31 | P99 vuelve a 720 ms | Métricas y trazas | Mantener observación |
Qué hora registrar
Siempre que sea posible, usar una zona horaria única, idealmente UTC, y conservar el timestamp original de la fuente. En logs distribuidos puede existir diferencia entre la hora en que el evento ocurrió y la hora en que el colector lo observó. El modelo de logs de OpenTelemetry separa Timestamp de ObservedTimestamp, precisamente para representar ambas.
La secuencia temporal prioriza, pero no prueba
Si los retries aumentan antes que el tiempo de espera del pool, esa secuencia convierte a los retries en una causa candidata. No demuestra por sí sola que sean la causa. Ambos cambios pueden depender de un tercer factor, como una latencia externa o un cambio de concurrencia.
La línea temporal sirve para responder:
- ¿Qué cambió primero?
- ¿Qué ocurrió inmediatamente antes del impacto?
- ¿Qué señal reaccionó después de una mitigación?
- ¿Qué eventos coinciden solo por agregación de ventanas?
Paso 4: usar métricas para localizar el síntoma
Las métricas permiten observar poblaciones completas y cambios en el tiempo. Son la señal adecuada para confirmar magnitud, tendencia, distribución y saturación.
La investigación debe avanzar desde el síntoma hacia los recursos que pueden explicarlo.
Primera capa: experiencia del servicio
Revisar por operación y población afectada:
- Rate de solicitudes lógicas.
- Intentos técnicos totales.
- Error rate técnico y funcional.
- P50, P95 y P99.
- Timeouts vistos por cliente y servidor.
- Consumo del SLO.
Separar solicitudes lógicas de intentos técnicos es crítico. Si 220 solicitudes por segundo producen 88 reintentos adicionales, el tráfico de usuario sigue siendo 220 solicitudes/s, pero el sistema ejecuta 308 intentos/s. Confundir ambos números oculta la amplificación.
Segunda capa: saturación y espera
Revisar:
- Longitud y edad de colas.
- Threads activos y en espera.
- Conexiones usadas, libres y máximas.
- Solicitudes pendientes de adquirir una conexión.
- Tiempo de espera en pools.
- Utilización de CPU, memoria y disco.
- Límites de concurrencia.
- Backpressure o rechazos.
La saturación no requiere que CPU o memoria estén al 100 %. Un pool de conexiones, un semáforo, una partición o un límite externo pueden convertirse en el recurso escaso mientras el host parece saludable.
OpenTelemetry define métricas para pools de base de datos como conexiones por estado, solicitudes pendientes, timeouts y tiempo de espera. Al 12 de julio de 2026, varias de estas convenciones figuran con estado Development, por lo que el soporte y los nombres disponibles deben validarse en cada SDK o librería.
Tercera capa: dependencias y mecanismos de resiliencia
Revisar:
- Latencia y errores por dependencia.
- Timeouts de conexión y lectura.
- Reintentos adicionales por operación.
- Estado del Circuit Breaker.
- Rechazos por bulkhead o rate limit.
- Fallbacks activados.
- Tiempo en DNS, TLS o adquisición de conexión cuando esté instrumentado.
Los mecanismos de resiliencia también generan carga. Un retry no es una abstracción gratuita: es una nueva ejecución que consume tiempo, conexiones, threads y cuota de la dependencia. El diseño de timeouts correctamente configurados y la prevención de tormentas de reintentos deben desarrollarse en su pieza especializada.
Pregunta principal: ¿qué cambió primero y en qué población?
Una secuencia útil puede ser:
- El P99 aumenta solo en una operación.
- El tráfico lógico permanece estable.
- Los intentos técnicos aumentan.
- Las solicitudes pendientes del pool crecen.
- La duración de las consultas permanece estable.
Esa combinación reduce la probabilidad de que la base de datos esté ejecutando consultas más lentas. Desplaza la investigación hacia la espera anterior a la consulta y hacia el mecanismo que multiplicó los intentos.
No usar el promedio como cierre
Un promedio puede volver al baseline mientras una cola residual mantiene una fracción de solicitudes degradadas. Los histogramas y percentiles permiten observar la distribución, pero su interpretación depende de buckets, ventana y población. Prometheus documenta que histogramas y summaries registran conteo y suma, y que el promedio se deriva de ambos; ese promedio no reemplaza la distribución.
Para profundizar en presupuestos, recorrido end-to-end y distribución de tiempos, consultar la guía de presupuesto de latencia.
Paso 5: usar trazas para localizar el recorrido degradado
Las métricas indican que existe una población anómala. Las trazas permiten inspeccionar ejecuciones individuales de esa población y ver cómo se distribuye el tiempo entre servicios y operaciones.
Una traza no debe elegirse al azar. Debe corresponder al alcance ya definido:
- Operación afectada.
- Ventana exacta.
- Región o zona.
- Versión.
- Resultado lento o fallido.
- Atributos relevantes del payload sin incluir datos sensibles.
Comparar tres tipos de traza
Seleccionar, si existen:
- Traza sana: misma operación y condiciones fuera del incidente.
- Traza lenta: completa, pero por encima del umbral.
- Traza fallida: termina en error o timeout.
La comparación debe observar:
- Camino crítico.
- Span que domina la duración.
- Espacios sin instrumentación.
- Espera antes de una dependencia.
- Reintentos representados como spans o eventos.
- Serialización y validaciones.
- Trabajo paralelo frente a secuencial.
- Colas o mensajería.
- Status y atributos de error.
El span más largo no siempre es la causa
Un span puede durar más porque espera a un recurso ya saturado. La duración localiza dónde se manifiesta el tiempo, pero la causa puede estar antes:
- Concurrencia excesiva.
- Retry que duplicó llamadas.
- Falta de backpressure.
- Contención por lock.
- Pool agotado.
- Dependencia que no respeta cancelación.
La traza reduce el espacio de búsqueda. No reemplaza la hipótesis.
Propagar contexto sin romper la traza
W3C Trace Context estandariza los encabezados traceparent y tracestate. Una implementación compatible debe, como mínimo, propagarlos para no romper la continuidad de la traza entre componentes.
Ese contexto permite que un trace_id represente el recorrido completo y que cada span_id identifique una operación concreta dentro de él. OpenTelemetry utiliza la propagación de contexto como mecanismo común para correlacionar señales a través de procesos y redes.
El sampling puede ocultar justo lo que se busca
Si la plataforma usa head sampling probabilístico, una traza lenta o con error puede no haberse conservado. OpenTelemetry señala que el head sampling decide sin observar la traza completa y no puede garantizar por sí solo la retención de todos los errores. El tail sampling permite decidir por latencia, error, atributos o versión, a cambio de mayor estado, complejidad y coste operativo.
Durante un incidente, antes de concluir “no hay trazas lentas”, validar:
- Tasa y política de sampling.
- Si los spans llegaron al collector.
- Si existe pérdida por cola o exportación.
- Si la consulta usa la ventana y atributos correctos.
- Si el tail sampler conserva errores y latencias altas.
Paso 6: correlacionar logs sin buscar a ciegas
Buscar ERROR en toda la plataforma suele producir mucho ruido y poca evidencia. Los logs son más útiles cuando la investigación ya tiene una operación, ventana, versión, dependencia y trace ID.
Campos mínimos de un log operativo
Un evento útil debería incluir, cuando aplique:
timestampdel origen.observed_timestampo timestamp de ingestión.service.namey versión.- Ambiente, región, zona e instancia.
trace_idyspan_id.- Operación o ruta normalizada.
- Dependencia.
- Resultado y código de error estable.
- Duración relevante.
- Número de intento.
- Atributos funcionales no sensibles y de cardinalidad controlada.
OpenTelemetry incluye Timestamp, ObservedTimestamp, TraceId, SpanId, severidad, recurso y atributos en su modelo estable de logs. También define la correlación por tiempo, contexto de ejecución y recurso de origen.
Ejemplo:
{
"timestamp": "2026-07-12T22:14:08.417Z",
"observed_timestamp": "2026-07-12T22:14:08.463Z",
"severity": "WARN",
"service": "orders-api",
"service_version": "2026.07.12-3",
"region": "south-1",
"trace_id": "4e8f9b87d1354f4f9c9770c7cb8a66d2",
"span_id": "63a3a6f34dcf1e80",
"operation": "create-order",
"dependency": "inventory-db",
"attempt": 2,
"pool_wait_ms": 1842,
"outcome": "timeout",
"error_code": "POOL_WAIT_TIMEOUT"
}
El ejemplo es ilustrativo. Los nombres concretos deben alinearse con el modelo de telemetría de la plataforma y con las convenciones soportadas por su instrumentación.
Orden de búsqueda recomendado
- Buscar el
trace_idde una traza lenta o fallida. - Filtrar por la ventana del span y el servicio relevante.
- Revisar eventos del span específico mediante
span_id. - Expandir a otras instancias solo si la evidencia lo exige.
- Agrupar por códigos estables y no por texto libre.
Qué evitar
- Buscar por mensajes completos que cambian con cada excepción.
- Usar la severidad como sustituto del impacto.
- Asumir que el log más dramático es la causa.
- Registrar secretos, tokens, payloads completos o datos personales.
- Generar un log por cada iteración de un fallo masivo y agravar la saturación.
- Concluir que no hubo error porque no apareció un log.
Un error puede estar representado en una métrica o span y no producir un log por sampling, nivel, pérdida de ingestión o falta de instrumentación. La ausencia de evidencia en una señal no es evidencia de ausencia en el sistema.
Paso 7: formular una hipótesis verificable
La investigación avanza cuando el equipo deja de enumerar posibilidades y formula una afirmación que puede ser refutada.
Estructura recomendada:
Creemos que X causa Y porque observamos Z. Si la hipótesis es correcta, al ejecutar W deberíamos observar Q. La descartaremos si aparece R.
Ejemplo:
Creemos que los reintentos están agotando el pool de conexiones porque los intentos adicionales aumentan antes que pending_requests, las trazas consumen tiempo antes del span de consulta y los logs muestran POOL_WAIT_TIMEOUT. Si limitamos los retries y la concurrencia interna, el tiempo de espera debería caer antes que la duración de consulta. Descartaremos la hipótesis si los waiters permanecen altos con el mismo tráfico total o si la consulta se vuelve más lenta de forma independiente.
Una hipótesis útil contiene una predicción
| Componente | Ejemplo |
|---|---|
| Mecanismo candidato | Reintentos aumentan la demanda sobre un pool limitado |
| Síntoma explicado | P99 alto y timeouts antes de ejecutar la consulta |
| Evidencia actual | Attempts, waiters y logs crecen en ese orden |
| Prueba | Limitar retries y concurrencia en una fracción controlada |
| Predicción | Cae pool_wait_time sin cambio en db.operation.duration |
| Evidencia que refuta | Wait time no cambia o la lentitud está dentro de la consulta |
No usar una etiqueta como explicación
Expresiones como “problema de red”, “base de datos lenta”, “Kubernetes”, “GC” o “saturación” describen categorías. No explican el mecanismo.
Una hipótesis debe especificar:
- Qué recurso o interacción falla.
- Bajo qué condición.
- Cómo produce el síntoma.
- Qué observación la confirmaría.
- Qué observación la refutaría.
Paso 8: separar evidencia, hipótesis, decisión y resultado
En una sala de incidente, las frases se mezclan con rapidez:
- “El pool está agotado”.
- “Subamos conexiones”.
- “La base está bien”.
- “El deploy lo causó”.
Sin clasificación, una suposición puede convertirse en hecho solo porque fue repetida.
Usar una tabla explícita:
| Tipo | Ejemplo |
|---|---|
| Evidencia | P99 subió de 600 ms a 2.4 s en create-order |
| Evidencia | pending_requests pasó de 0–3 a 65 |
| Hipótesis | Los retries amplificaron la demanda y agotaron el pool |
| Decisión | Limitar concurrencia y desactivar retry sobre timeout de adquisición |
| Resultado | Wait time cayó a baseline y P99 bajó a 720 ms |
| Pendiente | Demostrar qué cambio incrementó la concurrencia efectiva |
Paso 9: aplicar una mitigación
Una mitigación busca reducir el impacto. Debe evaluarse por riesgo, reversibilidad, velocidad, integridad y blast radius.
Opciones y trade-offs
| Mitigación | Cuándo puede servir | Riesgo principal | Señal de validación |
|---|---|---|---|
| Rollback | El cambio reciente es candidato y la versión previa es compatible | Revertir puede reintroducir otro defecto o migración incompatible | Diferencia clara entre versiones y recuperación tras rollback |
| Feature flag | La ruta degradada puede aislarse | Mantener estado parcial o experiencia inconsistente | Caen errores o latencia solo en la población afectada |
| Limitar concurrencia | Existe saturación por trabajo simultáneo | Menor throughput y crecimiento de cola externa | Baja wait time sin pérdida inaceptable de éxito |
| Load shedding | La capacidad no alcanza y debe protegerse el núcleo | Rechazo explícito de una fracción de tráfico | Sistema estable, latencia acotada y rechazos controlados |
| Reducir retries | Los intentos amplifican carga | Menor probabilidad de recuperación ante fallos transitorios | Caen intentos totales, waiters y timeouts |
| Aumentar capacidad | Hay headroom real en la dependencia | Desplazar la saturación a otro recurso o amplificar daño | Mejora proporcional sin degradar dependencia |
| Degradación controlada | Puede ofrecerse una respuesta parcial | Pérdida funcional temporal | SLO de modo degradado y experiencia predecible |
| Reinicio | Estado corrupto o fuga conocida y evidencia preservada | Destruir evidencia y obtener mejora temporal | Recuperación reproducible y mecanismo posteriormente demostrado |
Cambiar una variable por vez cuando el riesgo lo permite
En un incidente grave puede ser necesario combinar acciones. Si se aplican varias, deben registrarse con precisión y, cuando sea posible, escalonarse. De lo contrario, la recuperación no permite atribuir efecto.
Diseñar criterio de aborto
Antes del cambio, definir:
- Qué métrica debe mejorar.
- En qué dirección y población.
- Qué métrica no debe empeorar.
- Cuándo revertir la mitigación.
- Quién decide continuar.
Una mitigación sin criterio de aborto es otro experimento no controlado en producción.
Paso 10: verificar la recuperación
“Ya responde” no es una verificación.
La recuperación debe comprobarse en la misma población y con las mismas señales que confirmaron el incidente:
- P95 y P99.
- Error rate técnico y funcional.
- Tráfico lógico e intentos totales.
- Timeouts y retries.
- Cola: longitud y edad.
- Saturación del recurso candidato.
- SLO o burn rate.
- Integridad de datos.
- Backlog generado durante la degradación.
Comparar contra baseline, no contra el peor minuto
Que P99 baje de 2.4 s a 1.5 s indica mejora, no recuperación, si el baseline era 600 ms.
Definir:
- Baseline comparable por hora, día y carga.
- Rango normal, no solo un punto.
- Ventana de observación suficiente para cubrir retraso de telemetría, ciclos de retry, procesamiento de backlog y variaciones del tráfico.
No existe una ventana universal. Un servicio de alto volumen puede mostrar estabilidad estadística en minutos; un proceso batch horario requiere observar al menos el siguiente ciclo relevante.
Verificar desde fuera y desde dentro
Una recuperación robusta combina:
- Señal externa: usuario, sintético o SLI.
- Señal interna: colas, pools, dependencias.
- Evidencia individual: trazas sanas después de la mitigación.
- Consistencia funcional: no se perdieron ni duplicaron operaciones.
Google SRE señala que el monitoreo debe permitir comparar el comportamiento antes y después de un cambio. También advierte que la frescura de los datos importa: si la telemetría tarda demasiado, el equipo puede atribuir un efecto a la acción equivocada.
Caso práctico: latencia causada por espera en el pool
El siguiente escenario es construido para mostrar el método. Los valores no son una configuración recomendada ni un límite universal.
Escenario
Una API de creación de órdenes mantiene 220 solicitudes lógicas por segundo. Su P99 normal es 600 ms. A las 22:14 UTC, el P99 sube a 2.4 s y el error rate pasa de 0.3 % a 2.1 %.
La CPU permanece en 48–55 %. La duración de las consultas principales se mantiene alrededor de 85 ms. Sin embargo, aumenta el tiempo necesario para adquirir una conexión.
Paso A: confirmar y acotar
La degradación afecta:
- Operación:
create-order. - Región:
south-1. - Versión:
2026.07.12-3. - Nodos con una nueva configuración de concurrencia.
No afecta:
- Lecturas de órdenes.
- Región
north-1. - Versión anterior.
Paso B: observar intentos, no solo solicitudes
Antes del incidente:
- Solicitudes lógicas: 220/s.
- Retries adicionales: 4.4/s.
- Intentos totales: 224.4/s.
Durante el incidente:
- Solicitudes lógicas: 220/s.
- Retries adicionales: 88/s.
- Intentos totales: 308/s.
Cálculo:
intentos_totales = solicitudes_logicas + reintentos_adicionales
intentos_totales = 220 + 88 = 308 intentos/s
amplificacion = 308 / 220 = 1.40
El tráfico del usuario no aumentó. La carga técnica sí aumentó 40 %.
Paso C: revisar capacidad y espera
Supuestos observados:
- Pool máximo: 100 conexiones.
- Tiempo medio de uso por adquisición: 300 ms.
- Capacidad teórica simplificada:
100 / 0,3 = 333 adquisiciones/s. - Intentos durante el incidente: 308/s.
Ese cálculo no representa capacidad segura porque ignora variabilidad, overhead, transacciones largas y distribución de tiempos. Muestra que el sistema opera cerca del límite teórico. Al acercarse a la saturación, pequeñas variaciones producen colas y el tiempo de espera crece antes de que CPU o consultas parezcan anómalas.
Métricas observadas:
| Señal | Baseline | Incidente |
|---|---|---|
| Solicitudes lógicas | 220/s | 220/s |
| Reintentos adicionales | 4.4/s | 88/s |
| Intentos totales | 224.4/s | 308/s |
| Pool pending requests | 0–3 | 65 |
| P99 de pool wait | 45 ms | 1,840 ms |
| Duración consulta P99 | 110 ms | 118 ms |
| API P99 | 600 ms | 2,400 ms |
Paso D: comparar trazas
Traza sana:
create-order 540 ms
├─ validate-request 35 ms
├─ acquire-db-connection 18 ms
├─ insert-order 102 ms
├─ reserve-inventory 210 ms
└─ publish-event 75 ms
Traza lenta:
create-order 2,320 ms
├─ validate-request 37 ms
├─ acquire-db-connection 1,760 ms
├─ insert-order 108 ms
├─ reserve-inventory 225 ms
└─ publish-event 82 ms
La consulta no domina la diferencia. La espera ocurre antes de ejecutarla.
Paso E: correlacionar logs
Los logs asociados a los trace IDs lentos muestran:
attempt=2con mayor frecuencia.POOL_WAIT_TIMEOUT.- Misma versión de consulta.
- Ningún aumento equivalente de
db_query_timeout.
Paso F: formular la hipótesis
La versión 2026.07.12-3 elevó la concurrencia interna y activó retries sobre timeouts de adquisición. Los intentos adicionales llevaron el pool cerca de saturación; la cola de adquisición elevó el P99 y generó nuevos timeouts, que produjeron más retries.
Predicción:
Si se limita la concurrencia interna y se elimina el retry para POOL_WAIT_TIMEOUT, los intentos totales y el tiempo de espera deben caer antes que la duración de consulta.
Paso G: mitigar
Acciones escalonadas:
- Desactivar retry sobre timeout de adquisición mediante feature flag.
- Limitar concurrencia interna de la versión afectada.
- Mantener el pool en 100 conexiones hasta comprobar headroom en la base de datos.
No se aumenta el pool automáticamente porque la base podría convertirse en el siguiente recurso saturado.
Paso H: verificar
Después de la mitigación:
| Señal | Resultado |
|---|---|
| Solicitudes lógicas | 218–224/s |
| Reintentos adicionales | 5–7/s |
| Pool pending requests | 0–4 |
| P99 de pool wait | 52 ms |
| Duración consulta P99 | 115 ms |
| API P99 | 680–740 ms |
| Error rate | 0.35 % |
La secuencia importa:
- Caen los retries.
- Caen los intentos totales.
- Disminuyen los waiters.
- Baja el P99 de la API.
- La duración de consulta permanece estable.
Ese resultado respalda la hipótesis de amplificación y espera en el pool. Aún queda demostrar qué cambio concreto elevó la concurrencia y por qué la política de retry trataba un timeout de saturación como fallo transitorio recuperable.
Prevención derivada del caso
- Métrica explícita de solicitudes pendientes y wait time del pool.
- Contador separado de solicitudes lógicas, intentos y retries adicionales.
- Política de retry por tipo de fallo e idempotencia.
- Límite de concurrencia antes del pool.
- Prueba de carga con variabilidad y fallos parciales.
- Alerta por saturación antes de que el P99 exceda el SLO.
- Trazas que representen adquisición de conexión y cada intento.
- Runbook con criterio para reducir carga sin aumentar el pool a ciegas.
El mecanismo puede propagarse hacia fallos en cascada si los timeouts y retries consumen recursos en servicios aguas arriba.
Qué hacer cuando las señales se contradicen
La contradicción suele indicar que las señales observan poblaciones, relojes o etapas distintas.
Caso 1: las métricas muestran errores, pero los logs no
Posibles explicaciones:
- El error se registra en el proxy y no en la aplicación.
- El proceso termina antes de emitir o exportar el log.
- El nivel de logging filtra el evento.
- La ingestión perdió datos.
- La métrica cuenta un timeout del cliente que el servidor no percibe.
Decisión: validar el punto de medición, buscar una traza o señal externa y comprobar pérdida en la tubería de logs.
Caso 2: los logs muestran errores, pero no hay impacto visible
Posibles explicaciones:
- El error fue recuperado por retry o fallback.
- Afecta una ruta sin tráfico relevante.
- El log usa severidad
ERRORpara una condición esperada. - La métrica de éxito está agregada y oculta una población pequeña.
Decisión: medir frecuencia, población y resultado funcional antes de escalar el incidente.
Caso 3: las trazas no muestran los casos lentos
Posibles explicaciones:
- Sampling probabilístico.
- Tail sampling mal configurado.
- Consulta por operación o versión incorrecta.
- Spans incompletos o contexto roto.
- Exportador saturado.
Decisión: revisar política de sampling, pérdida de spans y propagación de traceparent.
Caso 4: cliente y servidor reportan latencias distintas
Posibles explicaciones:
- DNS, conexión, TLS o red antes de llegar al servidor.
- Cola en gateway o proxy.
- Respuesta enviada por servidor, pero recibida tarde por cliente.
- Diferencia de población: el servidor excluye requests abortadas.
Decisión: descomponer el recorrido y precisar dónde inicia y termina cada métrica.
Método para resolver contradicciones
- Validar la misma ventana temporal.
- Validar la misma población y etiquetas.
- Confirmar la unidad y definición de la métrica.
- Comparar timestamp de origen e ingestión.
- Revisar sampling y pérdida de telemetría.
- Buscar una señal independiente.
- Preferir la evidencia más cercana al resultado que se intenta explicar.
Errores frecuentes durante un incidente
Cambiar varias variables sin registro
Impide atribuir la recuperación y puede introducir una segunda falla.
Reiniciar antes de preservar evidencia
Elimina heaps, conexiones, colas, locks y estados que podían demostrar el mecanismo. Reiniciar puede ser necesario, pero debe ser una decisión consciente.
Investigar toda la plataforma
Aumenta el ruido. Primero se acota por operación, población, versión y dependencia.
Usar promedios para declarar recuperación
Oculta colas lentas y usuarios extremos. Debe revisarse la distribución.
Confundir correlación con causalidad
Dos señales simultáneas pueden compartir una causa. Se requiere una predicción y una prueba.
Culpar al último despliegue automáticamente
El despliegue es un candidato temporal, no una causa demostrada. Puede activar una condición latente o coincidir con un cambio externo.
Buscar logs antes de acotar
Produce consultas amplias, lentas y dominadas por eventos irrelevantes.
Tratar todo retry como recuperación
Un retry puede resolver un fallo transitorio o amplificar una saturación. Debe medirse como carga adicional.
Declarar causa raíz a partir de la mitigación
“Bajó al aumentar el pool” no demuestra que el pool estuviera mal dimensionado. Puede haber ocultado una fuga, un cambio de concurrencia o una transacción que retiene conexiones demasiado tiempo.
Cerrar sin verificar integridad y backlog
La latencia puede volver al baseline mientras quedan mensajes acumulados, transacciones duplicadas o procesos incompletos.
Para un marco más general de investigación estructurada de incidentes, el artículo de troubleshooting cubre el método de diagnóstico más allá de la correlación específica de señales de observabilidad.
Roles mínimos en una sala de incidente
No todos deben ejecutar consultas o proponer cambios al mismo tiempo.
Una estructura mínima:
- Incident lead: mantiene prioridad, alcance, decisiones y criterio de cierre.
- Investigador técnico: coordina hipótesis y pruebas.
- Comunicador: actualiza a stakeholders sin interrumpir la investigación.
- Responsable de línea temporal: registra eventos, decisiones y resultados.
En equipos pequeños, una persona puede asumir más de un rol. Lo importante es que las funciones existan y que el liderazgo no quede implícito.
El modelo de incident response descrito por Google se basa en funciones definidas y comunicación estandarizada para que la respuesta pueda escalar sin perder coordinación.
Después del incidente: documentar sin duplicar el diagnóstico
El postmortem debe registrar:
- Impacto y población afectada.
- Detección.
- Línea temporal.
- Causa técnica demostrada.
- Factores contribuyentes.
- Mitigación y recuperación.
- Qué aceleró o retrasó el diagnóstico.
- Acciones preventivas con owner y fecha.
Google SRE define el postmortem como un registro del incidente, impacto, mitigación, causas y acciones de seguimiento. También recomienda una cultura sin culpabilización que examine las condiciones del sistema y no convierta el documento en una sanción individual.
Las acciones sin propietario tienden a no completarse; el SRE Workbook recomienda ownership explícito y un único punto responsable con colaboradores.
Este artículo no desarrolla la disciplina completa de postmortems para evitar canibalizar la pieza dedicada. Consultar cómo documentar un postmortem para que el incidente no se repita.
Corregir los vacíos de observabilidad
La salida de un incidente no debe ser “agregar más logs” de forma indiscriminada.
La pregunta correcta es qué decisión no pudo tomarse y qué señal habría reducido esa incertidumbre.
Preguntas de revisión
- ¿Qué métrica de impacto faltó?
- ¿Qué dimensión impidió acotar la población?
- ¿Qué span no existía en el camino crítico?
- ¿Qué atributo faltó en la traza?
- ¿Qué log no incluía
trace_id, código estable o versión? - ¿Qué reloj o timestamp impidió ordenar eventos?
- ¿Qué política de sampling descartó los casos relevantes?
- ¿Qué alerta llegó tarde o sin contexto?
- ¿Qué dashboard mezcló solicitudes e intentos?
- ¿Qué runbook recomendaba una acción no validada?
Convertir el vacío en un requisito
Mal action item:
Mejorar observabilidad del pool.
Action item ejecutable:
Instrumentar pending_requests, timeouts y wait time por service.name, versión y pool; añadir enlaces desde el panel RED a trazas filtradas por operación; owner: equipo de plataforma; fecha: 2026-07-26; criterio de aceptación: una prueba de carga debe permitir distinguir espera por conexión de duración de consulta.
La telemetría útil no es la que acumula más datos. Es la que reduce una decisión incierta.
Checklist operativo
Detección
- La alerta representa impacto real o riesgo operacional.
- Se identificó la métrica principal que cambió.
- Se estimó el inicio del incidente.
- Se midió volumen y población afectada.
- Se distinguieron disponibilidad, éxito, latencia y percentiles.
- Se separaron solicitudes lógicas, intentos totales y retries adicionales.
Alcance
- Operación o endpoint.
- Servicio y dependencia.
- Región, zona o cluster.
- Versión.
- Canal, tenant o tipo de payload cuando sea relevante.
- Grupo sano comparable.
Línea temporal
- Primera alerta.
- Primer impacto confirmado.
- Despliegues y cambios de configuración.
- Variaciones de tráfico o dependencia.
- Mitigaciones con hora exacta.
- Resultado de cada acción.
Evidencia
- Métricas RED.
- Saturación, colas y pools.
- Traza sana.
- Traza lenta.
- Traza fallida, si existe.
- Logs correlacionados por trace/span ID.
- Política de sampling validada.
- Relojes y ventanas alineados.
Hipótesis
- Mecanismo causal candidato.
- Evidencia que lo respalda.
- Predicción medible.
- Prueba o mitigación reversible.
- Condición que refutaría la hipótesis.
Acción
- Riesgo y blast radius evaluados.
- Integridad de datos protegida.
- Criterio de aborto definido.
- Una variable por vez cuando el riesgo lo permite.
- Decisión y responsable registrados.
Recuperación
- Métricas comparadas contra baseline.
- P95/P99 y error rate normalizados.
- Colas y backlogs bajo control.
- Retries y timeouts normalizados.
- SLO o burn rate recuperado.
- Integridad y duplicados verificados.
- Ventana de observación suficiente para el patrón de carga.
Aprendizaje
- Causa técnica y factores contribuyentes separados.
- Mitigación distinguida de causa.
- Vacíos de observabilidad identificados.
- Acciones con owner, fecha y criterio de aceptación.
- Postmortem requerido según criterio previamente definido.
Preguntas frecuentes
¿Qué se revisa primero durante un incidente?
Primero se confirma el impacto y la población afectada. En servicios orientados a solicitudes, Rate, Errors y Duration ayudan a iniciar el triage; después se revisan saturación, colas, dependencias y mecanismos de resiliencia. Abrir logs de toda la plataforma antes de acotar suele aumentar el ruido.
¿Cuál es la diferencia entre mitigación y causa raíz?
La mitigación reduce el impacto. La causa explica el mecanismo que produjo el incidente y los factores que permitieron que escalara. Reiniciar, hacer rollback o aumentar capacidad puede recuperar el servicio sin demostrar la causa.
¿Cómo se usa un Trace ID?
El trace_id identifica el recorrido distribuido de una solicitud. Se usa para abrir la traza completa y para filtrar logs emitidos dentro de ese contexto. El span_id restringe la búsqueda a una operación concreta. La continuidad depende de propagar correctamente el contexto entre servicios.
¿Qué debe incluir una línea temporal?
Alertas, cambios de métricas, despliegues, cambios de configuración, fallos de dependencias, decisiones, mitigaciones y resultados. Debe construirse durante el incidente, con una zona horaria común y separando el timestamp de origen del de observación cuando existan retrasos de ingestión.
¿Cuándo debe cerrarse un incidente?
Cuando el impacto esté controlado, las señales principales hayan vuelto a un rango aceptable, el backlog y la integridad estén verificados, y la observación cubra un ciclo suficiente para el patrón de carga. Cerrar no exige haber terminado el postmortem, pero sí transferir claramente los riesgos y acciones pendientes.
¿Qué debe incluir un postmortem?
Impacto, detección, línea temporal, causa técnica, factores contribuyentes, mitigación, recuperación, aprendizajes y acciones con responsables y fechas. Debe centrarse en el sistema y en las condiciones de decisión, no en culpar a individuos.
Conclusión
Investigar un incidente no consiste en abrir todas las herramientas disponibles. Consiste en reducir incertidumbre de manera controlada.
Las métricas responden qué cambió, cuánto y para quién. Las trazas muestran en qué recorrido se consume el tiempo o aparece el error. Los logs aportan el estado y el evento concreto. Ninguna señal aislada entrega automáticamente la causa.
La secuencia operativa es:
- Proteger la operación y la integridad.
- Confirmar impacto real.
- Acotar la población afectada.
- Construir la línea temporal mientras ocurre el incidente.
- Usar métricas para localizar el síntoma.
- Usar trazas para reducir el recorrido.
- Usar logs para obtener contexto preciso.
- Formular una hipótesis con predicción y criterio de refutación.
- Mitigar de forma reversible.
- Verificar contra baseline, SLO, colas e integridad.
La prueba de una investigación sólida no es la cantidad de dashboards consultados. Es que cada decisión pueda vincularse con evidencia, que la recuperación sea medible y que el siguiente incidente encuentre menos zonas ciegas que el anterior.
Fuentes técnicas
- OpenTelemetry — Signals: opentelemetry.io/docs/concepts/signals
- OpenTelemetry — Context propagation: opentelemetry.io/docs/concepts/context-propagation
- OpenTelemetry — Logging: opentelemetry.io/docs/specs/otel/logs
- OpenTelemetry — Logs Data Model: opentelemetry.io/docs/specs/otel/logs/data-model
- OpenTelemetry — Sampling: opentelemetry.io/docs/concepts/sampling
- OpenTelemetry — Database client metrics: opentelemetry.io/docs/specs/semconv/db/database-metrics
- W3C — Trace Context: w3.org/TR/trace-context
- Google SRE — Monitoring Distributed Systems: sre.google/sre-book/monitoring-distributed-systems
- Google SRE Workbook — Monitoring: sre.google/workbook/monitoring
- Google SRE Workbook — Incident Response: sre.google/workbook/incident-response
- Google SRE — Postmortem Culture: sre.google/sre-book/postmortem-culture
- Google SRE Workbook — Postmortem Culture: sre.google/workbook/postmortem-culture
- Grafana Labs — Choose a RED metric: grafana.com/docs/grafana/latest/explore/simplified-exploration/traces/investigate/choose-red-metric
- Prometheus — Histograms and summaries: prometheus.io/docs/practices/histograms