Reservalia ya despliega sola, con entornos reproducibles, una estrategia de relevo elegida a conciencia y un botón de vuelta atrás ensayado. Y sin embargo sigue teniendo un agujero en el centro: se entera de que producción va mal porque llama un cliente. Los 3 minutos de detección que prometía la tabla de la lección anterior no existen todavía, comprobar-metricas.sh invoca unos umbrales que nadie ha definido, y el freeze de los viernes sigue en pie porque nadie tiene un argumento objetivo para retirarlo. Sin señal de producción, el despliegue continuo es simplemente desplegar a ciegas más rápido. Esta lección cierra el bucle —y con él, el módulo—: qué observar, cómo convertir esas observaciones en objetivos con consecuencias, cuándo merece la pena despertar a alguien, y cómo el propio pipeline se alimenta de lo que ocurre en producción.

Contenido

  1. El bucle abierto: por qué el CD sin monitoreo es una apuesta rápida
  2. Los tres pilares de la observabilidad
  3. Las cuatro señales de oro aplicadas a la API de Reservalia
  4. El panel mínimo de Reservalia
  5. SLI, SLO y presupuesto de error
  6. La política de presupuesto: adiós al freeze de los viernes
  7. Marcar los despliegues en los paneles
  8. Alertas: síntomas, no causas
  9. Retroalimentación hacia el pipeline: las métricas DORA se alimentan solas
  10. El cuadro de mando de Reservalia después de los módulos 2 y 3
  11. Errores Comunes y Consejos
  12. Ejercicios
  13. Conclusión

  1. El bucle abierto: por qué el CD sin monitoreo es una apuesta rápida

Todo lo construido hasta aquí forma una cadena que empuja cambios hacia producción cada vez más deprisa. Lo que falta es la flecha de vuelta.

flowchart LR
    C["commit"] --> CI["ci.yml"] --> CD["cd.yml"] --> P["prod"]
    P -->|"¿?"| S["Señal:<br/>¿funciona para los negocios?"]
    S -.->|"decide si se sigue desplegando"| C
    S -.->|"dispara rollback"| CD
    S -.->|"alimenta las métricas DORA"| M["Cuadro de mando"]

Sin esa flecha ocurren tres cosas concretas, todas visibles en Reservalia hoy: el canary de la 03-04 no puede decidir si promociona, porque comprobar-metricas.sh no tiene contra qué comparar; el rollback de la 03-05 llega tarde, porque la detección depende de que un cliente llame; y el equipo mantiene el freeze de los viernes porque su única alternativa a la prudencia ciega sería la temeridad ciega.

Conviene distinguir dos palabras que se usan como sinónimas. Monitorizar es vigilar cosas que ya sabes que pueden fallar: la CPU, la memoria, el número de errores. Observabilidad es la propiedad de un sistema que permite responder preguntas que no habías anticipado: "¿por qué las reservas de los negocios con horario partido tardan cuatro segundos solo los lunes?". La primera se configura; la segunda se diseña, instrumentando el código para que emita suficiente contexto.

  1. Los tres pilares de la observabilidad

Pilar Qué es Qué pregunta responde Coste En Reservalia
Métricas Números agregados en el tiempo ¿Hay un problema? ¿Cuánto de grande? Bajo y constante CloudWatch: latencia, 5xx, tareas sanas
Logs Eventos discretos con contexto ¿Qué pasó exactamente en esta petición? Alto: crece con el tráfico CloudWatch Logs, JSON estructurado
Trazas El recorrido de una petición por el sistema ¿Dónde se fue el tiempo? Medio, con muestreo OpenTelemetry (pendiente)

El orden importa y es el orden de una investigación: la métrica te avisa, la traza te localiza, el log te explica. Un equipo que solo tiene logs se entera tarde y busca a ciegas; uno que solo tiene métricas sabe que algo va mal pero no por qué.

Reservalia hace una inversión pequeña que multiplica el valor de sus logs: emitirlos en JSON estructurado con campos fijos.

// apps/api/src/log.ts — un log que se puede consultar, no solo leer
export function log(nivel: 'info' | 'error', mensaje: string, extra: Record<string, unknown> = {}) {
  console.log(JSON.stringify({
    ts: new Date().toISOString(),
    nivel,
    mensaje,
    commit: process.env.COMMIT_SHA,   // 1 · qué versión emitió esta línea
    entorno: process.env.ENTORNO,
    ...extra,                          // 2 · negocioId, rutaId, duracionMs…
  }));
}
  1. Incluir el commit en cada línea es lo que permite, durante un incidente, filtrar los errores por versión y comprobar en diez segundos si empezaron con el despliegue de las 09:08. Es la misma idea del endpoint /version, aplicada a los logs.
  2. Campos estructurados en lugar de texto interpolado. log('error', 'reserva fallida', { negocioId: 412, duracionMs: 3140 }) se puede agregar y filtrar; console.log('Error en reserva del negocio 412') solo se puede leer. La regla: nunca metas un dato variable dentro del texto del mensaje.

Una advertencia de coste que sorprende a muchos equipos: los logs son el pilar que más crece y más factura. Reservalia registra en info las operaciones de negocio (reserva creada, cancelada) y en error los fallos, pero no una línea por petición HTTP: para eso están las métricas, que cuestan una fracción.

  1. Las cuatro señales de oro aplicadas a la API de Reservalia

Las cuatro señales de oro son el conjunto mínimo que responde "¿mi servicio está bien?" para casi cualquier sistema con peticiones.

Señal Qué mide Métrica concreta en Reservalia Umbral de referencia
Latencia Cuánto tarda en responder p50, p95 y p99 de POST /api/reservas p95 < 400 ms
Tráfico Cuánta demanda hay Peticiones/minuto al ALB; reservas creadas/hora Contexto, no alarma
Errores Qué fracción falla Proporción de respuestas 5xx sobre el total < 0,1 %
Saturación Cuán lleno está el sistema CPU y memoria de las tareas ECS; conexiones libres del pool de RDS CPU < 70 %, pool < 80 %

Tres precisiones que separan un panel útil de uno decorativo:

La latencia se mide en percentiles, nunca en media. Si 99 peticiones tardan 100 ms y una tarda 10 segundos, la media es 199 ms —un número tranquilizador que oculta a un usuario que se ha ido—. El p95 dice "el 95 % de los usuarios espera menos que esto", y el p99 es donde viven los casos raros que acaban en el chat de soporte. Además, la latencia de los errores debe medirse aparte: un servicio que empieza a devolver 500 en dos milisegundos mejora su latencia media mientras se cae.

El tráfico casi nunca es una alarma, pero es imprescindible como contexto. Un error rate del 5 % con 20.000 peticiones y con 40 peticiones son incidentes de gravedad muy distinta, y una caída del tráfico a cero puede ser la única señal de que el frontal está roto aunque la API responda perfectamente.

La saturación es la única señal que avisa antes. Latencia, errores y tráfico describen lo que ya está pasando; el pool de conexiones al 85 % dice que dentro de veinte minutos habrá un incidente. Es la señal que permite actuar en lugar de reaccionar.

  1. El panel mínimo de Reservalia

Nuria crea un único panel, reservalia-api-prod, con la regla de que debe caber en una pantalla y responder en diez segundos a la pregunta "¿está bien?".

Fila Widgets Por qué está
1 · Estado Peticiones/min · % de 5xx · p95 global · tareas sanas / deseadas El semáforo: cuatro números que resumen la salud
2 · Camino crítico p95 y errores de POST /api/reservas y de GET /huecos El negocio es reservar; el resto es secundario
3 · Dependencias Latencia de RDS · conexiones libres del pool · errores del proveedor de SMS Dónde suele estar la causa real
4 · Presupuesto Presupuesto de error consumido este mes · versión desplegada por entorno La decisión de si se puede seguir desplegando
// apps/api/src/middleware/metricas.ts — una métrica por petición, sin librería pesada
app.use((req, res, next) => {
  const inicio = process.hrtime.bigint();
  res.on('finish', () => {
    const ms = Number(process.hrtime.bigint() - inicio) / 1e6;
    emitirMetrica({
      nombre: 'ApiLatencia',
      valor: ms,
      unidad: 'Milliseconds',
      dimensiones: {                       // 1
        ruta: req.route?.path ?? 'desconocida',
        metodo: req.method,
        clase: `${Math.floor(res.statusCode / 100)}xx`,
      },
    });
  });
  next();
});
  1. Las dimensiones son la clave y también la trampa. Permiten filtrar por ruta, método y clase de respuesta, que es justo lo que hace falta para saber si el problema es general o de un endpoint. Pero cada combinación distinta de dimensiones es una métrica facturable: usar req.path en lugar de req.route.path crearía una métrica por cada /api/negocios/412/huecos, es decir, una por negocio, con una factura de tres cifras y paneles inservibles. Nunca uses identificadores como dimensión.

  1. SLI, SLO y presupuesto de error

Un panel te dice cómo está el sistema; no te dice si eso es aceptable. Para eso hacen falta tres conceptos encadenados.

Concepto Qué es Ejemplo en Reservalia
SLI (indicador) Una medida concreta de la experiencia del usuario % de peticiones a la API que no devuelven 5xx
SLO (objetivo) El valor que ese indicador debe alcanzar en una ventana ≥ 99,9 % en 30 días naturales
SLA (acuerdo) Un SLO con consecuencias contractuales No aplica: Reservalia no firma penalizaciones
Presupuesto de error Lo que sobra hasta el 100 %: fallo permitido 0,1 % de las peticiones del mes

Reservalia define dos SLO, y solo dos. La tentación de definir quince es fuerte y es un error: un SLO que nadie mira no disciplina nada.

SLO SLI Objetivo Ventana Presupuesto
Disponibilidad Peticiones sin 5xx / peticiones totales 99,9 % 30 días 0,1 % ≈ 43 min de caída total
Latencia de reserva Peticiones a POST /api/reservas servidas en < 400 ms 99,0 % 30 días 1 % de las reservas

Tres decisiones de diseño merecen explicación. Se mide desde el punto de vista del usuario, no del servidor: el SLI cuenta peticiones que llegaron al ALB, incluidas las que fallaron porque no había ninguna tarea sana; medir solo lo que la aplicación consiguió procesar es medirse a uno mismo con la nota puesta. El objetivo no es el 100 %, y esto es lo que más cuesta aceptar: el 100 % es imposible (falla la red, falla AWS, falla el cliente) e indeseable, porque el coste de cada nueve adicional se multiplica y ese dinero sale de construir producto. 99,9 % en 30 días son 43 minutos de presupuesto, que es exactamente el material con el que se compra la capacidad de desplegar deprisa.

Porque esa es la idea central: el presupuesto de error no es un mal que hay que evitar, es un recurso que hay que gastar. Un equipo que termina el mes con el 100 % del presupuesto intacto no ha sido excelente: ha sido demasiado conservador, ha desplegado menos de lo que podía y ha entregado menos valor del que podía. Un equipo que lo agota el día 12 tiene un problema de fiabilidad. El objetivo es llegar a fin de mes habiéndolo gastado casi todo.

  1. La política de presupuesto: adiós al freeze de los viernes

En la lección 03-01 dejamos el freeze de los viernes calificado como deuda técnica, con fecha de retirada y condiciones. El presupuesto de error es la regla objetiva que lo sustituye, porque responde a la misma preocupación —"no quiero romper producción en mal momento"— con datos en lugar de con calendario.

Presupuesto restante Qué se puede hacer Quién decide
> 50 % Desplegar con normalidad, cualquier día de la semana El pipeline, sin intervención
25 – 50 % Se sigue desplegando, pero la fiabilidad entra en la planificación del sprint Marta
10 – 25 % Solo correcciones, cambios de fiabilidad y trabajo de bajo riesgo Marta + Nuria
< 10 % Congelación de funcionalidades: todo el equipo a fiabilidad hasta recuperar Acordado de antemano

Las tres propiedades que hacen que esto funcione mejor que un freeze:

  • Es objetivo. No depende de que hoy alguien esté nervioso. La regla se acuerda cuando nadie está en un incidente, que es el único momento en que se piensa con claridad.
  • Es simétrico. Si la fiabilidad va bien, el equipo gana libertad: se despliega el viernes a las cinco. El freeze solo restringía; el presupuesto también premia.
  • Alinea a todo el mundo. Producto deja de pedir "más funcionalidades y también más estabilidad" como si fueran independientes: el presupuesto hace explícito que son la misma moneda.

Reservalia retira el freeze de los viernes el día que se cumplen las tres condiciones que la 03-01 dejó escritas —rollback demostrado en un simulacro cronometrado, detección automática de incidentes graves, y un historial de aprobaciones que no filtraba nada— y lo sustituye por esta tabla. La primera semana sin freeze, Diego fusiona un cambio un viernes a las 16:40; el canary lo promociona a las 17:10 y no pasa absolutamente nada. Ese no-suceso es el resultado del módulo entero.

  1. Marcar los despliegues en los paneles

La pregunta que se hace un equipo ante una degradación es siempre la misma: ¿esto ha empezado con el último despliegue? Responderla mirando dos pestañas y comparando marcas de tiempo es lento y propenso a error. La solución es barata: anotar cada despliegue sobre las gráficas.

      # cd.yml, tras el smoke test de prod
      - name: Anotar el despliegue en el panel
        run: |
          aws cloudwatch put-metric-data --namespace Reservalia/Despliegues \
            --metric-name Despliegue --value 1 \
            --dimensions Entorno=prod,Commit=${{ steps.meta.outputs.sha }}

Con esa métrica superpuesta como línea vertical sobre las gráficas de latencia y errores, la correlación se ve de un vistazo: si la curva se tuerce justo en la línea, el sospechoso está identificado; si se torció veinte minutos antes, el despliegue es inocente y hay que mirar hacia las dependencias. Es el mismo razonamiento que aplicamos a los logs con el campo commit, llevado a las gráficas, y es lo que hace que la primera pregunta de un incidente se responda en segundos en lugar de en diez minutos.

Un matiz honesto: correlación no es causalidad. Un despliegue coincidente puede ser casualidad —a las 09:00 se despliega y empieza el pico de tráfico matinal—. La anotación no cierra la investigación; la empieza por el sitio correcto.

  1. Alertas: síntomas, no causas

Una alerta debe cumplir tres condiciones: es real (no ruido), es urgente (no puede esperar a mañana) y es accionable (quien la recibe puede hacer algo). Si falla alguna, no es una alerta: es un correo.

La distinción fundamental es entre alertar sobre causas y alertar sobre síntomas.

Alerta por causa Alerta por síntoma
Ejemplo "CPU de la tarea al 91 %" "El 3 % de las reservas falla"
Problema Puede no afectar a nadie; hay infinitas causas posibles
Ventaja Cubre causas que nadie anticipó, incluida la que fallará mañana
Cuándo sirve Como predicción con margen (disco al 85 %) Siempre: es la referencia

Alertar por causas produce el peor de los mundos: muchas notificaciones que no significan nada para el usuario y, aun así, huecos —el día que el sistema falla por un motivo que nadie previó, no hay alerta—. Reservalia define tres alertas y ni una más:

Alerta Condición Gravedad Acción
ApiErrores5xx > 1 % de 5xx durante 5 min en prod Despierta Mirar despliegue reciente, mitigar
ApiLatenciaReservas p95 de POST /api/reservas > 1 s durante 10 min Despierta Igual: es un síntoma de usuario
PresupuestoConsumoRapido Se consume el 10 % del presupuesto mensual en 1 h Despierta Incidente en curso, aunque el porcentaje total aún sea bueno
PoolConexionesAlto Conexiones libres < 20 % durante 15 min Ticket Revisar en horario laboral
FlagsCaducados Hay flags de release vencidos Ticket semanal Retirar deuda (03-05)

La tercera merece un comentario, porque es la más sofisticada. Un SLO mensual tiene un problema: si el sistema se cae del todo un día 2, el porcentaje mensual acumulado todavía se ve bien durante horas y no salta nada. La velocidad de consumo del presupuesto —burn rate— mide cuánto se está gastando ahora, y detecta en minutos una caída que el porcentaje mensual tardaría un día en reflejar. Es la alerta que convierte un SLO en algo operativo y no solo en un informe.

Sobre la fatiga de alertas: es el fallo más común y el más caro, porque no se manifiesta como un incidente sino como una lenta pérdida de confianza. Un equipo que recibe treinta notificaciones al día deja de leerlas —no por indisciplina, sino porque es humanamente inevitable— y el día que llega la importante, se pierde entre las demás. Tres reglas de higiene: si una alerta no ha requerido ninguna acción las últimas cinco veces, se borra o se convierte en ticket; toda alerta que despierta lleva enlace a un procedimiento escrito con los primeros tres pasos; y el número de alertas que despiertan se revisa cada mes y debe tender a la baja.

La prueba definitiva antes de crear una alerta que suene de madrugada: ¿qué haría una persona a las 3:40 al recibirla? Si la respuesta es "mirarla y volver a dormirse", esa alerta no debe existir.

  1. Retroalimentación hacia el pipeline: las métricas DORA se alimentan solas

En la lección 01-05 construimos el cuadro de mando DORA con las tablas despliegues e incidentes, rellenadas a mano. Un cuadro de mando que depende de que alguien recuerde escribir una fila está desactualizado en tres semanas. Ahora que el pipeline conoce cada despliegue y las alertas conocen cada incidente, ambas tablas pueden llenarse solas.

      # cd.yml, último paso del job de prod
      - name: Registrar el despliegue
        if: always()                                        # 1
        run: |
          psql "$DATABASE_URL_METRICAS" <<SQL
          INSERT INTO despliegues
            (entorno, commit_sha, iniciado_en, terminado_en, exito, run_id, primer_commit_en)
          VALUES
            ('prod', '${{ steps.meta.outputs.sha }}',
             '${{ steps.meta.outputs.inicio }}', now(),
             ${{ job.status == 'success' }},
             '${{ github.run_id }}',                        -- 2
             '${{ steps.meta.outputs.fecha_primer_commit }}')   -- 3
          ON CONFLICT (run_id, entorno) DO NOTHING;          -- 4
          SQL
  1. if: always() registra también los despliegues fallidos. Sin ellos, el change failure rate mediría solo los éxitos y daría siempre 0 %, que es la forma más común de tener una métrica preciosa e inútil.
  2. run_id enlaza la fila con la ejecución de GitHub Actions: desde el cuadro de mando se llega a los logs en un clic.
  3. fecha_primer_commit es lo que permite calcular el lead time de verdad, que se mide desde que se escribió el código y no desde que empezó el despliegue. Se obtiene con git log -1 --format=%cI sobre el commit más antiguo del PR.
  4. ON CONFLICT DO NOTHING hace la inserción idempotente, como exigía la 03-02: relanzar el workflow no duplica la fila ni contamina las métricas.

Los incidentes se registran igual, desde la alerta y desde el propio rollback.yml de la 03-05, que ya recibía un motivo obligatorio precisamente para esto. Con las dos tablas al día, las cuatro métricas son consultas:

-- Frecuencia de despliegue y change failure rate de los últimos 30 días
SELECT
  count(*) FILTER (WHERE exito) / 4.3            AS despliegues_por_semana,
  round(100.0 * count(*) FILTER (WHERE NOT exito) / count(*), 1) AS pct_fallidos,
  round(avg(extract(epoch FROM terminado_en - primer_commit_en) / 3600)::numeric, 1) AS lead_time_horas
FROM despliegues
WHERE entorno = 'prod' AND terminado_en > now() - interval '30 days';

Una precisión metodológica sobre el change failure rate: no cuenta los despliegues que fallaron en el pipeline —esos son buenas noticias, el sistema hizo su trabajo—, sino los que llegaron a producción y hubo que arreglar o revertir. La forma práctica de medirlo es contar los despliegues seguidos de un rollback o de un incidente en las 24 horas siguientes, que es justo lo que permite cruzar despliegues con incidentes.

  1. El cuadro de mando de Reservalia después de los módulos 2 y 3

Este es el resultado del trabajo de dos módulos, medido con la misma vara de la línea base:

Métrica DORA Línea base Objetivo Ahora Qué lo consiguió
Frecuencia de despliegue 1,1 / semana ≥ 5 / semana 12 / semana cd.yml automático; sin freeze
Lead time for changes 6,2 días < 4 h 3,5 h PR pequeños, CI de 4 min, despliegue de 30 min
Change failure rate 14 % < 5 % 6,5 % ⚠️ Quality gate, canary y circuit breaker
Time to restore 68 min < 10 min 9 min Alertas, flags y rollback.yml

Tres de cuatro objetivos cumplidos, y el cuarto a medio camino. Merece la pena mirar por qué se ha atascado el change failure rate, porque la respuesta no está en este módulo: los fallos que quedan no son de despliegue, son de contenido —una dependencia que cambió de comportamiento en una actualización menor, una migración de esquema que bloqueó una tabla en horario laboral, un caso de negocio que las pruebas no cubrían—. Eso es exactamente lo que aborda el módulo siguiente.

Y hay una mejora que ninguna tabla recoge. El ritual del viernes de la lección 01-04 —tres horas de SFTP, migraciones a mano en psql, Diego mirando logs— ha desaparecido. No se ha optimizado: ha dejado de existir como categoría de trabajo. Marta, Diego y Nuria dedican ese tiempo a otra cosa, y ese es el beneficio real que las cuatro métricas solo insinúan.

Lo que queda pendiente, y que da forma al módulo 4:

  • El pipeline es lento y se está engordando. El CI tarda 4 minutos hoy; con más pruebas serán 15, y Diego dejará de mirarlo. Hacen falta caché, paralelismo y ejecución selectiva.
  • Las dependencias no están bajo control. Nadie sabe cuántos paquetes transitivos entran en reservalia/api, ni quién los mantiene, ni qué versión exacta se usó en a3f9c21.
  • El pipeline tiene permisos sobre producción y no se ha auditado. Desde la 03-01 sabemos que dejó de ser una herramienta interna para convertirse en un sistema crítico, y sigue sin análisis de seguridad, firma de artefactos ni inventario de componentes.
  • Las migraciones de base de datos siguen siendo el punto frágil. Son la única razón por la que el rollback de la 03-05 puede no funcionar.

Diego: "Si el CI tarda más que ir a por un café, dejo de mirarlo. Y ahora que el despliegue es mío hasta producción, lo miro mucho más."

Errores Comunes y Consejos

Error 1: medir la media en lugar de percentiles. Oculta exactamente a los usuarios que peor lo están pasando. Error 2: alertar sobre causas. Produce ruido y, a la vez, huecos ante fallos no anticipados.

Error 3: definir quince SLO. Un SLO que nadie consulta no disciplina nada; dos que se miran cada semana cambian el comportamiento del equipo. Error 4: poner el objetivo en el 100 %, que hace el presupuesto igual a cero y convierte cualquier despliegue en una violación.

Error 5: usar identificadores como dimensión de una métrica. Un negocioId como dimensión multiplica el coste por 340 y hace el panel ilegible. Error 6: paneles que nadie mira, construidos con todo lo que la herramienta ofrecía en lugar de con lo que responde una pregunta.

Error 7: registrar solo los despliegues con éxito. El change failure rate saldrá siempre estupendo y no significará nada.

Consejo 1: define los SLO con producto, no solo con ingeniería. El objetivo de fiabilidad es una decisión de negocio disfrazada de decisión técnica. Consejo 2: acuerda la política de presupuesto por escrito y en frío, antes del primer incidente que la ponga a prueba. Consejo 3: revisa las alertas una vez al mes y borra sin piedad las que no han provocado ninguna acción.

Ejercicios

Ejercicio 1

El panel de Reservalia muestra un p95 estable en 180 ms durante toda la semana, pero soporte reporta tres negocios que se quejan de lentitud al abrir la agenda. El equipo responde que "las métricas están bien". Explica qué puede estar ocurriendo y qué tres cambios harías en la instrumentación.

Ejercicio 2

Es día 18 del mes. El presupuesto de error de disponibilidad está consumido al 78 % por una caída de RDS del día 6. Producto pide desplegar una funcionalidad grande esta semana. Aplica la política del apartado 6, argumenta la decisión y explica qué harías si producto insiste con un motivo de negocio legítimo.

Ejercicio 3

Diseña la alerta que detectaría, en menos de cinco minutos, un despliegue que provoca que el 100 % de las reservas de un solo negocio grande falle, mientras el resto de negocios funciona con normalidad. Discute por qué las tres alertas actuales de Reservalia probablemente no lo detectarían.

Soluciones

Solución 1. Lo más probable es que las métricas estén bien medidas y mal agregadas. Un p95 global sobre todas las rutas mezcla miles de peticiones baratas (/salud, listados en caché) con las caras: si el 92 % del tráfico responde en 30 ms, hay margen de sobra para que un endpoint concreto tarde varios segundos sin mover el p95 global. Además, tres negocios sobre 340 son menos del 1 % del tráfico: por definición viven en el p99, invisibles en el p95. Y hay una tercera posibilidad: que la lentitud esté en el frontal —descarga de recursos, renderizado— y la API no la vea en absoluto.

Los tres cambios: (1) medir percentiles por ruta, no solo globales, y llevar al panel el p95 y el p99 de las rutas del camino crítico; (2) añadir el p99 junto al p95, porque los problemas que reporta soporte viven ahí, y complementarlo con logs estructurados que registren las peticiones por encima de un umbral (por ejemplo, 1 s) con su negocioId, lo que permitiría descubrir en un minuto que los tres negocios afectados son los que tienen horario partido y 400 citas semanales; (3) instrumentar el cliente (Real User Monitoring) para medir lo que experimenta el navegador, que es lo único que el usuario percibe. La lección de fondo: un SLI que no representa la experiencia del usuario es un número que tranquiliza sin informar.

Solución 2. Con el 78 % consumido queda el 22 %, así que la política sitúa a Reservalia en la franja de 10-25 %: solo correcciones, cambios de fiabilidad y trabajo de bajo riesgo. La decisión por defecto es no desplegar la funcionalidad grande esta semana, y la conversación con producto no debería ser una negociación de voluntades sino la aplicación de una regla acordada previamente.

Ahora bien, hay un matiz técnico importante y honesto: el presupuesto se agotó por una caída de RDS ajena a los despliegues, no por cambios del equipo. Bloquear la entrega por un incidente de infraestructura castiga la conducta equivocada, y una política que se percibe injusta se acaba ignorando. Dos salidas legítimas: revisar si esa caída debe excluirse del cálculo (muchos equipos definen de antemano qué eventos son excepcionales y cómo se documentan), o mantener la restricción pero acompañarla de la acción que la resuelve —trabajo de fiabilidad sobre RDS: Multi-AZ ya lo hay, faltará revisar reintentos, tiempos de espera y degradación elegante—.

Si producto insiste con un motivo legítimo (un compromiso comercial con fecha), la respuesta correcta no es saltarse la política en silencio, sino usar las herramientas del módulo: desplegar el código detrás de un feature flag apagado, activarlo para un negocio, luego para el 10 % y solo después para todos, con rollback inmediato disponible. Eso desacopla la fecha de entrega del riesgo, que es precisamente para lo que se construyó todo esto. Y la excepción se anota: quién la autorizó y por qué, para revisarla en la retrospectiva.

Solución 3. Las tres alertas actuales no lo detectarían por un problema de dilución. Un negocio grande puede suponer el 2 % del tráfico total; si todas sus reservas fallan, el error rate global sube del 0,1 % al 2,1 %, que probablemente supera el umbral del 1 % de ApiErrores5xx… o probablemente no, si el negocio es más pequeño o si el fallo solo afecta a una parte de sus peticiones. Con un negocio del 0,5 % del tráfico, la señal global es indistinguible del ruido, y lo mismo ocurre con la latencia y con el consumo de presupuesto.

El diseño que sí lo detecta: una alerta sobre el error rate máximo por negocio, no sobre el agregado. En la práctica se implementa emitiendo una métrica de errores agrupada por una dimensión de cardinalidad controlada —no negocioId, que serían 340 métricas y viola la regla del apartado 4, sino algo como el segmento de tamaño del negocio, o un contador de "negocios distintos con más del 50 % de peticiones fallidas en los últimos 5 minutos"—. Esa última formulación es la buena: un solo número, cardinalidad uno, que salta cuando cualquier negocio está completamente roto aunque el agregado esté impecable. Condición: ≥ 1 negocio con más del 50 % de fallos durante 5 minutos, sobre un mínimo de 20 peticiones para evitar falsos positivos de negocios con poco tráfico.

Complemento imprescindible: cuando esa alerta salte, hace falta poder responder "¿qué negocio?", y eso no lo dan las métricas sino los logs estructurados con negocioId del apartado 2. Es la ilustración perfecta del orden de los tres pilares: la métrica avisa, el log explica.

Conclusión

El bucle está cerrado. Reservalia ya no despliega a ciegas: tiene métricas, logs estructurados y trazas con papeles distintos —la métrica avisa, la traza localiza, el log explica—; vigila las cuatro señales de oro en un panel que cabe en una pantalla; ha traducido "¿está bien?" en dos SLO con un presupuesto de error de 43 minutos al mes que decide, con una tabla acordada en frío, cuándo se despliega con libertad y cuándo toca frenar; marca cada despliegue sobre las gráficas para que la primera pregunta de un incidente se responda en segundos; alerta sobre síntomas y no sobre causas, con tres alertas que despiertan y ninguna más; y alimenta sus métricas DORA automáticamente desde el propio pipeline, incluidos los despliegues fallidos.

El freeze de los viernes ha desaparecido, y no por valentía sino por lo contrario: porque ahora existe una regla objetiva que dice cuándo se puede desplegar y cuándo no, y porque un despliegue que se deshace en cuatro minutos y se detecta en dos deja de merecer una ceremonia. Los números lo respaldan: de 1,1 a 12 despliegues por semana, de 6,2 días a 3,5 horas de lead time, de 68 a 9 minutos de recuperación. El change failure rate se ha quedado en el 6,5 % frente al objetivo del 5 %, y esa es la pista honesta de por dónde sigue el trabajo.

Porque los fallos que quedan ya no son de despliegue. Son de un pipeline que empieza a engordar y a hacerse lento, de dependencias que entran en el artefacto sin que nadie sepa cuántas ni de quién son, de un sistema con permisos sobre producción que nunca ha pasado una revisión de seguridad, y de migraciones de esquema que siguen siendo el único motivo por el que el botón de vuelta atrás podría no funcionar. El módulo 4, Prácticas Avanzadas de CI/CD, ataca esos cuatro frentes, y empieza por el que los ordena a todos: su primera lección, Pipelines de CI/CD, disecciona la anatomía completa de un pipeline —sus etapas, cómo se orquestan, qué se paraleliza, qué se puede saltar y cómo se diseña uno que siga siendo rápido cuando el equipo haya triplicado su tamaño.

Curso de CI/CD: Integración y Despliegue Continuo

Módulo 1: Introducción a CI/CD

Módulo 2: Integración Continua (CI)

Módulo 3: Despliegue Continuo (CD)

Módulo 4: Prácticas Avanzadas de CI/CD

Módulo 5: Implementación de CI/CD en Proyectos Reales

Módulo 6: Herramientas y Tecnologías

Módulo 7: Ejercicios Prácticos

Módulo 8: Recursos Adicionales

© Copyright 2026. Todos los derechos reservados