Hexadevs
Volver al blog

Debugging en producción: cuando el bug solo aparece cuando miles de personas miran

Por Equipo Hexadevs · 30 sept 2026 · 4 min de lectura

El bug que solo aparece en producción es una categoría aparte. En tu local funciona. En staging, también. Pero con 50k usuarios concurrentes y zonas horarias que no probaste, explota. Las técnicas que necesitás para debuggear esto se aprenden después del “Hola Mundo”.

El cambio de mentalidad: de reproducir a observar

En local reproducís el bug, lo abrís en el debugger y listo. En producción no podés tocar nada. Tu trabajo pasa de reproducir a observar: recolectar la información suficiente para entender qué pasó sin interferir con el sistema.

Para eso necesitás tres cosas: logs estructurados, tracing distribuido y una forma de aislar el problema sin tocar el código desplegado.

Logs estructurados: el mínimo decente

// Mal: log libre que no se puede parsear
console.log("user tried to login", userId, "and failed")

// Bien: log estructurado
logger.info({
  event: "login_failed",
  userId: "42",
  reason: "invalid_password",
  ip: "203.0.113.4",
  duration_ms: 234,
})

La diferencia es que el segundo se puede filtrar, agrupar y contar. event es un nombre estable. El resto son campos tipados que varían. Con eso ya podés responder preguntas como “¿cuántos logins fallidos hubo en la última hora agrupados por reason?”.

Librerías útiles: pino para Node, structlog para Python, zap para Go.

Tracing distribuido: cuando un request pasa por 5 servicios

Un request hoy típicamente pasa por: CDN → API gateway → servicio de auth → servicio de orders → DB. Si en algún lado tarda 4 segundos, necesitás ver dónde.

import { trace } from "@opentelemetry/api"

const span = trace.getActiveSpan()
span?.setAttribute("user.id", userId)
span?.setAttribute("order.total", total)

// Cuando algo falla
span?.recordException(error)
span?.setStatus({ code: SpanStatusCode.ERROR })

OpenTelemetry es el estándar. Lo integrás con Datadog, Honeycomb, Grafana Tempo, Sentry o el vendor que uses. Lo importante es empezar: aunque uses solo el SDK sin backend, ya tenés spans exportables.

Feature flags: debuggear sin hacer deploy

if (await featureFlags.isEnabled("new-checkout-flow", userId)) {
  return newCheckout(order)
}
return legacyCheckout(order)

Las feature flags te permiten:

  • Activar funcionalidades para un usuario específico (userId === "debug-user-42").
  • Hacer rollback en producción sin deploy: cambiás un flag y el código viejo vuelve.
  • Testear en producción con un % de tráfico (canary release al 5%).

Librerías: LaunchDarkly, Unleash, Flagsmith, o un sistema casero con Redis para empezar.

Postmortem: lo que se hace DESPUÉS del incidente

# Postmortem: latencia elevada en /api/orders — 2026-09-15

## Resumen
A las 14:32 UTC, /api/orders experimentó latencia p99 de 8 segundos
durante 23 minutos. 0.4% de requests fallaron.

## Timeline
- 14:32 — Alertas de Datadog disparan por p99 > 5s.
- 14:35 — Se identifica que el deploy de las 14:25 cambió el query plan.
- 14:41 — Rollback manual al release anterior.
- 14:55 — Métricas vuelven a la normalidad.

## Root cause
Una migración añadió un índice faltante en staging, pero el script no
se ejecutó en producción. El nuevo query generó un full table scan.

## Acción correctiva
- [ ] Bloquear deploys de migraciones sin checklist explícito.
- [ ] Alertas adicionales sobre query plans con cambios > 30%.
- [ ] Documentar el procedimiento de rollback en el runbook.

Postmortem no es buscar culpables. Es construir memoria institucional sobre qué se rompió, por qué y cómo evitar que vuelva a pasar. La referencia clásica es el capítulo sobre postmortems del libro Site Reliability Engineering de Google.

Los cinco mandamientos del debugging en producción

  1. Nunca debuggees mirando tu propio usuario. Creá un usuario de prueba con datos deliberados.
  2. Todo cambio grande se hace con feature flag, no con redeploy.
  3. Cada incidente tiene un postmortem. Sin excepciones.
  4. Los logs que no tienen event no son logs, son console.log.
  5. Si no podés responder “qué falló y por qué” en 15 minutos, te faltan herramientas, no capacidad.

Si tu sistema no tiene logs estructurados, tracing y feature flags, no podés debuggearlo bien. No es una mejora, es infraestructura básica.

Cuando empieces a tener estas piezas en su lugar, los incidentes dejan de ser emergencias y pasan a ser problemas de ingeniería resolubles. Esa es la línea entre un dev que sufre producción y uno que la opera.