Dentro de seis meses, alguien en Reservalia preguntará: "¿ha servido de algo todo esto?". Si el equipo responde "sí, ahora vamos mucho más rápido", la conversación se convertirá en una discusión de sensaciones. Si responde "el tiempo desde el commit hasta producción ha bajado de 9 días a 40 minutos y el porcentaje de despliegues que provocan incidente ha pasado del 15 % al 3 %", la conversación se acaba. Esta lección va de eso: de convertir la calidad de la entrega de software en números que se pueden verificar. Las métricas DORA son el estándar del sector para hacerlo, y su mayor virtud es que son solo cuatro, se calculan con datos que el propio pipeline genera, y no se pueden manipular a la vez —mejorar velocidad estropeando estabilidad se ve inmediatamente. Al terminar sabrás qué mide cada una, de qué evento del pipeline sale el dato, cómo instrumentarlas sin comprar herramienta alguna, y por qué convertirlas en objetivos individuales es la forma más rápida de destruir su utilidad.
Contenido
- Qué son las métricas DORA y por qué son cuatro
- Métrica 1: frecuencia de despliegue
- Métrica 2: lead time for changes
- Métrica 3: change failure rate
- Métrica 4: time to restore service
- La quinta métrica: fiabilidad
- Rangos orientativos de rendimiento
- Cómo instrumentarlas de forma sencilla
- Calcular el lead time con bash y json
- Consultar las métricas con SQL
- El cuadro de mando inicial de Reservalia
- La ley de Goodhart: cuando la métrica se convierte en objetivo
- Errores comunes y consejos
- Ejercicios
- Conclusión
- Qué son las métricas DORA y por qué son cuatro
DORA son las siglas de DevOps Research and Assessment, el programa de investigación que durante años ha encuestado a decenas de miles de profesionales para identificar qué prácticas distinguen a los equipos que entregan software mejor. Su aportación más útil y más citada es un conjunto de cuatro métricas que resumen el rendimiento de la entrega.
Lo interesante no es la lista, es su estructura. Las cuatro se agrupan en dos parejas que tiran en direcciones opuestas:
graph TB
subgraph V["⚡ VELOCIDAD (¿con qué rapidez entregamos?)"]
V1["1· Frecuencia de despliegue<br/>¿cada cuánto llega algo a producción?"]
V2["2· Lead time for changes<br/>¿cuánto tarda un cambio en llegar?"]
end
subgraph E["🛡️ ESTABILIDAD (¿con qué calidad entregamos?)"]
E1["3· Change failure rate<br/>¿qué porcentaje de cambios rompe algo?"]
E2["4· Time to restore service<br/>¿cuánto tardamos en arreglarlo?"]
end
V -.->|"se equilibran"| E
style V fill:#cfe8ff
style E fill:#d9f2d9
Esta tensión es lo que hace que el conjunto sea difícil de falsear:
- Si solo midieras velocidad, la forma trivial de "mejorar" sería desplegar sin probar nada. La estabilidad se hundiría y se vería al instante.
- Si solo midieras estabilidad, la forma trivial de "mejorar" sería no desplegar nunca. La velocidad se hundiría y también se vería.
El hallazgo central del programa es contraintuitivo y merece leerse dos veces: velocidad y estabilidad no se oponen; van juntas. Los equipos que despliegan más a menudo también fallan menos y se recuperan antes. La razón la vimos en la lección 01-02: desplegar a menudo obliga a lotes pequeños, y los lotes pequeños son más fáciles de verificar, de diagnosticar y de revertir. El miedo a desplegar produce lotes grandes, y los lotes grandes producen incidentes. Es un círculo, y se puede recorrer en los dos sentidos.
- Métrica 1: frecuencia de despliegue
Qué mide. Con qué frecuencia una organización lleva código a producción con éxito.
2.1. Cómo se calcula
frecuencia de despliegue = nº de despliegues exitosos a producción
──────────────────────────────────────
periodo de tiempoTres precisiones que cambian mucho el resultado:
- Solo producción. Los despliegues a
devystagingno cuentan. Lo que mide la métrica es cuánto valor llega a los usuarios. - Solo los exitosos. Un despliegue que se revierte inmediatamente no cuenta como entrega; contará en la métrica 3.
- Por servicio desplegable, no por empresa. Si Reservalia despliega
apiywebpor separado, se mide cada una. Sumar servicios de toda la organización produce un número grande y sin significado.
2.2. De qué evento del pipeline sale el dato
Del final del job de despliegue a producción, cuando termina correctamente. Es el dato más fácil de capturar de los cuatro: basta con registrar una fila cada vez que un despliegue a prod acaba en verde.
2.3. Qué te dice realmente
La frecuencia de despliegue es un indicador indirecto del tamaño del lote, y por eso importa tanto. Un equipo que despliega una vez cada dos semanas está acumulando dos semanas de cambios en cada entrega, con todo lo que eso implica (sección 4 de la lección 01-02).
También revela cuánta fricción tiene el proceso. Nadie despliega diez veces al día si cada despliegue cuesta tres horas de trabajo manual. La frecuencia baja casi nunca es una decisión: es un síntoma.
- Métrica 2: lead time for changes
Qué mide. El tiempo que transcurre desde que un cambio se confirma en el repositorio hasta que está funcionando en producción.
Es probablemente la métrica más valiosa de las cuatro, porque atraviesa todo el proceso.
3.1. Cómo se calcula
Se calcula para cada commit y se reporta como mediana (o percentil 50) del periodo. Aquí hay una decisión metodológica importante:
Usa la mediana, no la media. Un solo cambio que se quedó tres meses en una rama olvidada destroza la media y no representa nada. La mediana te dice cuánto tarda el cambio típico, que es lo que quieres saber. El percentil 90 también es útil: te dice cómo de malo es el peor caso habitual.
3.2. De qué evento del pipeline sale el dato
De dos eventos, y por eso es la métrica que más gente calcula mal:
| Extremo | Dónde está el dato | Cómo se obtiene |
|---|---|---|
| Inicio | Metadatos del commit en Git | git show -s --format=%cI <sha> |
| Fin | Registro del despliegue a producción | Marca de tiempo del job de despliegue |
El error habitual es medir desde que arranca el pipeline en lugar de desde el commit. Eso mide el rendimiento del pipeline (útil, pero es otra cosa) y oculta precisamente lo que suele ser el problema: el tiempo de espera. En Reservalia, el pipeline tardaría 8 minutos, pero el cambio espera hasta 9 días al viernes. Si mides desde el arranque del pipeline, tu lead time es de 8 minutos y estarías engañándote.
3.3. Un matiz sobre commits y despliegues
Un despliegue suele incluir varios commits. El lead time se calcula por commit: cada uno de los commits incluidos en el despliegue recibe la misma fecha de fin, pero tiene su propia fecha de inicio.
gantt
title Lead time de tres commits desplegados juntos
dateFormat YYYY-MM-DD HH:mm
axisFormat %d/%m %H:%M
section Commits
commit a3f9c21 (lead time 26 h) :a1, 2026-03-13 09:00, 26h
commit b7e2d10 (lead time 5 h) :a2, 2026-03-14 06:00, 5h
commit c1d4a55 (lead time 1 h) :a3, 2026-03-14 10:00, 1h
Los tres se despliegan a las 11:00 del 14 de marzo, pero sus lead times son muy distintos. La mediana de esos tres sería 5 horas.
3.4. Qué te dice realmente
El lead time descompone el proceso. Cuando es alto, el diagnóstico consiste en preguntarse dónde se va el tiempo:
| Tramo | Qué lo alarga | Dónde se ataca en el curso |
|---|---|---|
| Commit → pipeline arrancado | Nada, si el trigger es automático | 02-07 |
| Pipeline de verificación | Suite lenta, sin paralelismo, sin caché | 04-04 |
| Pipeline → revisión aprobada | Revisiones lentas, PR demasiado grandes | 02-07 |
| Merge → despliegue disponible | Falta de automatización del despliegue | 03-02 |
| Despliegue disponible → producción | Ventanas de despliegue, aprobaciones lentas, miedo | 03-01, 03-04 |
En la inmensa mayoría de equipos, el tramo dominante es el último. Y ese no se arregla comprando runners más rápidos.
- Métrica 3: change failure rate
Qué mide. El porcentaje de despliegues a producción que provocan una degradación del servicio y requieren una intervención correctiva inmediata (rollback, corrección urgente, parche).
4.1. Cómo se calcula
change failure rate = despliegues que causaron un fallo × 100
───────────────────────────────────────
total de despliegues a producción4.2. La parte difícil: definir "fallo"
Esta es la métrica más subjetiva de las cuatro, y su valor depende por completo de que el equipo acuerde una definición antes de empezar a medir y no la cambie después. Una definición operativa razonable para Reservalia:
Un despliegue cuenta como fallido si, como consecuencia directa, ocurre alguna de estas cosas:
- Hubo que revertirlo.
- Hubo que desplegar una corrección urgente fuera del flujo normal en las horas siguientes.
- Se degradó el servicio de forma perceptible para los usuarios (errores, lentitud grave, funcionalidad rota).
- Hubo que activar un feature flag de emergencia para desactivar lo desplegado.
No cuenta como fallido:
- Un fallo detectado en
stagingy que nunca llegó a producción. Eso es el sistema funcionando. - Un bug que llevaba tres meses en producción y se descubre ahora: no lo causó este despliegue.
- Una caída de un proveedor externo no relacionada con el cambio.
Escribid esa definición en el repositorio. Sin ella, la métrica se vuelve inservible en cuanto haya un caso ambiguo y alguien decida sobre la marcha.
4.3. De qué evento del pipeline sale el dato
Este es el único dato de los cuatro que no sale automáticamente del pipeline: requiere una decisión humana. Las fuentes prácticas son:
- Un rollback automático disparado por las métricas: se registra solo (03-05).
- Un despliegue marcado a mano como fallido por quien gestiona el incidente.
- La vinculación entre el incidente y el despliegue que lo causó, hecha en el post mortem.
Lo más práctico es un comando o un botón que Nuria pueda usar durante el incidente:
# Marcar el último despliegue de producción como fallido.
# Lo ejecuta quien gestiona el incidente, mientras lo gestiona.
./scripts/marcar-despliegue-fallido.sh \
--despliegue dep_2026_0314_1042 \
--motivo "error 500 al crear citas tras el cambio de esquema" \
--detectado-en "2026-03-14T11:05:00+01:00"Si registrar el fallo cuesta más de treinta segundos, nadie lo hará durante una crisis y tus datos serán falsos.
4.4. Qué te dice realmente
Un change failure rate alto apunta a huecos concretos en la verificación: pruebas insuficientes, entorno de staging que no se parece a producción, o lotes demasiado grandes. Un valor sospechosamente bajo (0 % sostenido) suele significar que no se está registrando, no que no falla nada.
- Métrica 4: time to restore service
Qué mide. Cuánto tarda la organización en restablecer el servicio cuando se produce una degradación o caída en producción.
5.1. Cómo se calcula
Se reporta como mediana de los incidentes del periodo.
Ojo con los dos extremos:
- Inicio del incidente: cuando el problema empezó a afectar a los usuarios, no cuando alguien se dio cuenta. Si el servicio estuvo roto 25 minutos antes de que llamara un cliente, esos 25 minutos cuentan. Medir desde la detección premia tener mala monitorización, que es exactamente el incentivo contrario al deseable.
- Restablecimiento: cuando los usuarios vuelven a estar bien, no cuando se entiende la causa raíz. Un rollback restablece el servicio aunque nadie sepa todavía qué pasó. El análisis viene después.
5.2. De qué evento sale el dato
De la gestión del incidente: hora de inicio y hora de resolución. Idealmente, la hora de inicio la aporta la monitorización automática (materia de 03-06) y no la memoria de nadie.
5.3. Qué te dice realmente
Es, junto con la frecuencia, la métrica que más rápido mejora al automatizar. En Reservalia hoy, restablecer significa recompilar y volver a subir por SFTP: alrededor de una hora. Con artefactos inmutables en ECR, restablecer es redesplegar la imagen anterior: minutos.
Esta métrica captura una idea profunda de DevOps: no se puede evitar que los fallos ocurran; sí se puede hacer que duren poco. Un equipo que falla el 5 % de las veces pero se recupera en 4 minutos ofrece un servicio mucho mejor que uno que falla el 2 % y tarda 6 horas.
- La quinta métrica: fiabilidad
A las cuatro clásicas se añadió después una quinta: la fiabilidad (reliability). Es distinta de las anteriores en su naturaleza y por eso conviene explicarla aparte.
Qué mide. Hasta qué punto el servicio cumple las expectativas de sus usuarios en cuanto a disponibilidad, latencia y corrección.
Las cuatro primeras miden el proceso de entrega; la quinta mide el resultado operativo. Es la que impide un fallo de razonamiento tentador: un equipo puede tener las cuatro métricas en verde y, aun así, ofrecer un servicio malo —lento, con funcionalidad correcta pero inservible, o caído fuera de los momentos que cuentan como "incidente".
No tiene una fórmula única. Se instrumenta mediante objetivos de nivel de servicio (SLO) definidos por el propio equipo. Para Reservalia, tres razonables:
| Objetivo de nivel de servicio | Umbral | Por qué este |
|---|---|---|
| Disponibilidad de la API | ≥ 99,9 % mensual en horario comercial | Una caída a las 4 de la mañana molesta menos que una a las 11:00 de un sábado |
| Latencia de creación de cita | percentil 95 < 800 ms | Si reservar es lento, el cliente final abandona |
| Éxito del envío de recordatorios | ≥ 99,5 % enviados en la ventana correcta | Un recordatorio que no llega es una cita perdida para el negocio |
Fíjate en el matiz del primero: "en horario comercial". Una plataforma de reservas para peluquerías y clínicas se juega su valor entre las 9:00 y las 20:00. Un objetivo de disponibilidad plano ignora eso. Definir bien un SLO consiste precisamente en capturar lo que de verdad le importa al usuario.
Las herramientas para medir esto —observabilidad, paneles y alertas— se ven en la lección 03-06.
- Rangos orientativos de rendimiento
El programa DORA clasifica a los equipos en cuatro niveles. Estos son los rangos orientativos:
| Métrica | Bajo | Medio | Alto | Elite |
|---|---|---|---|---|
| Frecuencia de despliegue | Menos de una vez al mes | Entre una vez al mes y una vez a la semana | Entre una vez a la semana y una vez al día | Bajo demanda, varias veces al día |
| Lead time for changes | Más de un mes | Entre una semana y un mes | Entre un día y una semana | Menos de un día |
| Change failure rate | Alto (en torno al 40 % o más) | Moderado (en torno al 20-30 %) | Moderado-bajo (en torno al 15 %) | Bajo (en torno al 5 % o menos) |
| Time to restore service | Más de una semana | Entre un día y una semana | Menos de un día | Menos de una hora |
7.1. Advertencia imprescindible sobre esta tabla
Estos rangos son referencias para orientarte, no objetivos que perseguir a ciegas. Cuatro razones concretas:
- Los umbrales se mueven. Cada edición del informe reajusta las fronteras. Lo que hace unos años era "elite" hoy es "alto". Perseguir una etiqueta es perseguir un objetivo móvil.
- El contexto lo cambia todo. Un equipo que desarrolla software médico certificado nunca desplegará varias veces al día, y eso no lo convierte en un mal equipo: lo convierte en un equipo que cumple la normativa de su sector. Comparar un SaaS con un sistema de aviónica no tiene sentido.
- Comparar equipos con estas etiquetas es tóxico. Sirven para compararte contigo mismo a lo largo del tiempo. En el momento en que se usan para rankings internos entre equipos, empieza la manipulación de datos (sección 12).
- "Elite" no es el objetivo correcto para todos. Para Reservalia, pasar de desplegar una vez a la semana a hacerlo una vez al día sería una transformación enorme. Fijarse "varias veces al día" como meta inicial solo produce frustración.
La pregunta correcta no es "¿en qué nivel estamos?" sino "¿vamos mejor que hace tres meses?".
- Cómo instrumentarlas de forma sencilla
No hace falta comprar ninguna herramienta. Basta con registrar un evento por despliegue y otro por incidente. Con eso se calculan tres de las cuatro métricas directamente, y la cuarta con una marca manual.
8.1. El modelo de datos mínimo
-- Todo lo necesario para las métricas DORA cabe en dos tablas.
CREATE TABLE despliegues (
id TEXT PRIMARY KEY, -- dep_2026_0314_1042
servicio TEXT NOT NULL, -- 'api' | 'web'
entorno TEXT NOT NULL, -- 'dev' | 'staging' | 'prod'
commit_sha TEXT NOT NULL,
commit_fecha TIMESTAMPTZ NOT NULL, -- ← inicio del lead time
desplegado_en TIMESTAMPTZ NOT NULL, -- ← fin del lead time
resultado TEXT NOT NULL, -- 'exito' | 'fallo_pipeline'
fallido BOOLEAN NOT NULL DEFAULT false, -- ← change failure rate
motivo_fallo TEXT,
commits_incluidos INTEGER NOT NULL DEFAULT 1,
pipeline_url TEXT
);
CREATE TABLE incidentes (
id TEXT PRIMARY KEY,
servicio TEXT NOT NULL,
inicio TIMESTAMPTZ NOT NULL, -- cuando empezó a AFECTAR a usuarios
restablecido TIMESTAMPTZ, -- NULL mientras siga abierto
despliegue_id TEXT REFERENCES despliegues(id), -- si lo causó un despliegue
severidad TEXT NOT NULL -- 'critica' | 'alta' | 'media'
);Dos decisiones de diseño que conviene entender:
commit_fechase guarda en la tabla, en lugar de consultarla a Git cada vez. Los repositorios se reescriben, las ramas se borran y las consultas a Git son lentas. Guardar el dato en el momento del despliegue lo congela.despliegue_idenincidenteses opcional. No todos los incidentes los causa un despliegue (puede caerse un proveedor). Esa relación es justamente la que permite calcular el change failure rate sin contaminarlo con incidentes ajenos.
8.2. Dónde se rellena cada campo
flowchart LR
A["Job de despliegue<br/>a prod termina OK"] -->|"INSERT"| B[("tabla despliegues")]
C["Monitorización detecta<br/>degradación"] -->|"INSERT"| D[("tabla incidentes")]
E["Nuria marca el<br/>despliegue culpable"] -->|"UPDATE fallido=true"| B
F["Servicio restablecido"] -->|"UPDATE restablecido"| D
B --> G["📊 Cuadro de mando<br/>4 métricas"]
D --> G
- Calcular el lead time con bash y json
Veamos el mecanismo concreto, paso a paso. Primero, obtener los dos extremos.
9.1. Los datos de partida
#!/usr/bin/env bash
# registrar-despliegue.sh
# Se ejecuta como ÚLTIMO paso del job de despliegue a producción.
set -euo pipefail # -e: aborta si algo falla | -u: error si hay variable no definida
# -o pipefail: un fallo en una tubería no pasa desapercibido
SHA="$(git rev-parse HEAD)"
# Fecha del COMMIT, en formato ISO 8601 con zona horaria.
# %cI = "committer date, strict ISO 8601". Es el inicio del lead time.
COMMIT_FECHA="$(git show -s --format=%cI "$SHA")"
# Fecha del DESPLIEGUE: ahora mismo, en UTC. Es el fin del lead time.
DESPLIEGUE_FECHA="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "Commit : $SHA"
echo "Commiteado: $COMMIT_FECHA"
echo "Desplegado: $DESPLIEGUE_FECHA"Por qué ISO 8601 con zona horaria. Un
2026-03-14 10:22sin zona es ambiguo: ¿hora de Madrid, UTC, del runner? Con cambios de hora de por medio, esa ambigüedad produce lead times negativos o de una hora de más. Trabaja siempre en UTC internamente y convierte solo al mostrar.
9.2. Calcular la diferencia
# Convertimos ambas fechas a segundos desde la época Unix y restamos.
# Esto elimina de un plumazo los problemas de zonas horarias y meses.
COMMIT_EPOCH="$(date -d "$COMMIT_FECHA" +%s)"
DESPLIEGUE_EPOCH="$(date -d "$DESPLIEGUE_FECHA" +%s)"
LEAD_TIME_SEG=$(( DESPLIEGUE_EPOCH - COMMIT_EPOCH ))
LEAD_TIME_MIN=$(( LEAD_TIME_SEG / 60 ))
LEAD_TIME_H=$(( LEAD_TIME_SEG / 3600 ))
echo "Lead time: ${LEAD_TIME_SEG}s = ${LEAD_TIME_MIN} min = ${LEAD_TIME_H} h"Un ejemplo con números reales:
# Commit : 2026-03-13T09:00:00+01:00 → epoch 1773388800
# Desplegado: 2026-03-14T11:00:00Z → epoch 1773486000
# Diferencia: 97200 segundos = 1620 minutos = 27 horas9.3. Construir el registro en JSON
# Generamos el evento como JSON. jq garantiza un escapado correcto:
# construir JSON concatenando cadenas con comillas es una fuente clásica
# de ficheros corruptos en cuanto un mensaje de commit lleva comillas.
jq -n \
--arg id "dep_$(date -u +%Y%m%d_%H%M%S)" \
--arg servicio "api" \
--arg entorno "prod" \
--arg sha "$SHA" \
--arg commit_f "$COMMIT_FECHA" \
--arg desp_f "$DESPLIEGUE_FECHA" \
--argjson lead "$LEAD_TIME_SEG" \
--argjson commits "$(git rev-list --count "${SHA_ANTERIOR}..${SHA}")" \
'{
id: $id,
servicio: $servicio,
entorno: $entorno,
commit_sha: $sha,
commit_fecha: $commit_f,
desplegado_en: $desp_f,
lead_time_segundos:$lead,
commits_incluidos: $commits,
resultado: "exito",
fallido: false
}' > despliegue.json
cat despliegue.jsonResultado:
{
"id": "dep_20260314_110000",
"servicio": "api",
"entorno": "prod",
"commit_sha": "a3f9c21e4b7d8f012345678901234567890abcde",
"commit_fecha": "2026-03-13T09:00:00+01:00",
"desplegado_en": "2026-03-14T11:00:00Z",
"lead_time_segundos": 97200,
"commits_incluidos": 3,
"resultado": "exito",
"fallido": false
}9.4. Calcular el lead time de cada commit del despliegue
Recuerda la sección 3.3: un despliegue incluye varios commits y cada uno tiene su propio lead time. Este script los calcula todos:
#!/usr/bin/env bash
# lead-time-por-commit.sh <sha_desplegado_anterior> <sha_actual>
set -euo pipefail
SHA_ANTERIOR="$1" # lo que había en producción
SHA_ACTUAL="$2" # lo que acabamos de desplegar
AHORA_EPOCH="$(date -u +%s)"
# git rev-list lista todos los commits entre ambos puntos.
# --format=%H|%cI da: hash|fecha ISO. --no-commit-header evita líneas extra.
git rev-list --format="%H|%cI" --no-commit-header "${SHA_ANTERIOR}..${SHA_ACTUAL}" \
| while IFS='|' read -r sha fecha; do
commit_epoch="$(date -d "$fecha" +%s)"
lead_min=$(( (AHORA_EPOCH - commit_epoch) / 60 ))
printf '%s %s lead_time=%d min\n' "${sha:0:7}" "$fecha" "$lead_min"
doneSalida de ejemplo:
c1d4a55 2026-03-14T10:00:00+01:00 lead_time=60 min
b7e2d10 2026-03-14T06:00:00+01:00 lead_time=300 min
a3f9c21 2026-03-13T09:00:00+01:00 lead_time=1620 minTres commits, tres lead times muy distintos. La mediana es 300 minutos (5 horas). La media sería 660 minutos, muy distorsionada por el commit antiguo: exactamente el motivo por el que se usa la mediana.
- Consultar las métricas con SQL
Con la tabla despliegues poblada, las métricas son consultas de pocas líneas.
10.1. Frecuencia de despliegue
-- Despliegues exitosos a producción, por semana, del servicio 'api'.
SELECT
date_trunc('week', desplegado_en) AS semana,
COUNT(*) AS despliegues
FROM despliegues
WHERE entorno = 'prod'
AND servicio = 'api'
AND resultado = 'exito'
AND desplegado_en >= now() - interval '12 weeks'
GROUP BY semana
ORDER BY semana; semana | despliegues
------------+-------------
2026-01-05 | 1
2026-01-12 | 1
2026-01-19 | 0
2026-01-26 | 2 ← una corrección urgente además del viernesEl patrón de "1 por semana" delata inmediatamente el ritual del viernes de Reservalia.
10.2. Lead time (mediana y percentil 90)
-- Mediana y P90 del lead time, en horas, por mes.
SELECT
date_trunc('month', desplegado_en) AS mes,
ROUND(
PERCENTILE_CONT(0.5) WITHIN GROUP (
ORDER BY EXTRACT(EPOCH FROM (desplegado_en - commit_fecha))
) / 3600.0, 1
) AS lead_time_mediana_h,
ROUND(
PERCENTILE_CONT(0.9) WITHIN GROUP (
ORDER BY EXTRACT(EPOCH FROM (desplegado_en - commit_fecha))
) / 3600.0, 1
) AS lead_time_p90_h,
COUNT(*) AS n
FROM despliegues
WHERE entorno = 'prod' AND resultado = 'exito'
GROUP BY mes
ORDER BY mes;Explicación de la consulta, para quien no haya visto PERCENTILE_CONT:
desplegado_en - commit_fechada un intervalo;EXTRACT(EPOCH FROM ...)lo convierte a segundos.PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY ...)calcula la mediana de esos segundos.- Se divide entre 3600 para pasarlo a horas.
- Se incluye
COUNT(*)siempre: una mediana calculada sobre 2 despliegues no significa nada, y sin el recuento no lo sabrías.
10.3. Change failure rate
-- Porcentaje de despliegues a producción que provocaron un fallo, por mes.
SELECT
date_trunc('month', desplegado_en) AS mes,
COUNT(*) AS total,
COUNT(*) FILTER (WHERE fallido) AS fallidos,
ROUND(100.0 * COUNT(*) FILTER (WHERE fallido) / COUNT(*), 1) AS pct_fallo
FROM despliegues
WHERE entorno = 'prod' AND resultado = 'exito'
GROUP BY mes
ORDER BY mes; mes | total | fallidos | pct_fallo
------------+-------+----------+-----------
2026-01-01 | 5 | 1 | 20.0
2026-02-01 | 4 | 0 | 0.0
2026-03-01 | 4 | 1 | 25.0Nótese el WHERE resultado = 'exito': el denominador son los despliegues que llegaron a producción. Un pipeline que falla antes de desplegar no es un cambio fallido: es el sistema protegiéndote.
10.4. Time to restore service
-- Mediana del tiempo de restablecimiento, en minutos, por trimestre.
SELECT
date_trunc('quarter', inicio) AS trimestre,
COUNT(*) AS incidentes,
ROUND(
PERCENTILE_CONT(0.5) WITHIN GROUP (
ORDER BY EXTRACT(EPOCH FROM (restablecido - inicio))
) / 60.0, 1
) AS restauracion_mediana_min
FROM incidentes
WHERE restablecido IS NOT NULL -- solo incidentes ya cerrados
AND severidad IN ('critica', 'alta')
GROUP BY trimestre
ORDER BY trimestre;10.5. Las cuatro de un vistazo
-- Cuadro de mando: las cuatro métricas del último trimestre.
WITH ventana AS (
SELECT * FROM despliegues
WHERE entorno = 'prod' AND resultado = 'exito'
AND desplegado_en >= now() - interval '90 days'
)
SELECT
'Frecuencia de despliegue' AS metrica,
ROUND(COUNT(*) / 12.85, 2) || ' por semana' AS valor
FROM ventana
UNION ALL
SELECT
'Lead time (mediana)',
ROUND(PERCENTILE_CONT(0.5) WITHIN GROUP (
ORDER BY EXTRACT(EPOCH FROM (desplegado_en - commit_fecha))
) / 3600.0, 1) || ' h'
FROM ventana
UNION ALL
SELECT
'Change failure rate',
ROUND(100.0 * COUNT(*) FILTER (WHERE fallido) / NULLIF(COUNT(*), 0), 1) || ' %'
FROM ventana
UNION ALL
SELECT
'Time to restore (mediana)',
ROUND(PERCENTILE_CONT(0.5) WITHIN GROUP (
ORDER BY EXTRACT(EPOCH FROM (restablecido - inicio))
) / 60.0, 1) || ' min'
FROM incidentes
WHERE restablecido IS NOT NULL AND inicio >= now() - interval '90 days';El NULLIF(COUNT(*), 0) evita una división por cero cuando no hay despliegues en la ventana: un detalle pequeño que provoca errores reales en cuadros de mando los meses tranquilos.
- El cuadro de mando inicial de Reservalia
Marta ha dedicado una tarde a reconstruir los datos del último trimestre a partir del historial de Git, del canal del equipo y de las notas de las incidencias. Este es el punto de partida medido —el número más importante de todo el curso, porque es contra el que compararemos todo lo demás:
| Métrica | Reservalia hoy | Nivel orientativo | De dónde sale el dato |
|---|---|---|---|
| Frecuencia de despliegue | 1,1 por semana | Medio | 14 despliegues a prod en 13 semanas |
| Lead time for changes (mediana) | 6,2 días | Medio | Mediana de 47 commits desplegados en el trimestre |
| Change failure rate | 14 % | Alto | 2 de 14 despliegues provocaron incidencia grave |
| Time to restore service (mediana) | 68 minutos | Alto | Mediana de las 2 incidencias graves |
| Fiabilidad (disponibilidad en horario comercial) | 99,4 % | Por debajo de su objetivo (99,9 %) | Registros del balanceador |
Y estos son los objetivos que el equipo se fija para el final del curso:
| Métrica | Hoy | Objetivo | Palanca principal | Módulo |
|---|---|---|---|---|
| Frecuencia de despliegue | 1,1 / semana | ≥ 5 / semana | Eliminar la ventana del viernes; despliegue automatizado | 3 |
| Lead time (mediana) | 6,2 días | < 4 horas | Suprimir la espera; CI rápida; despliegue automático a staging | 2 y 3 |
| Change failure rate | 14 % | < 5 % | Pruebas automatizadas en cada PR; lotes pequeños; canary | 2 y 3 |
| Time to restore | 68 min | < 10 min | Artefactos inmutables; rollback en un comando; alertas | 3 |
| Disponibilidad comercial | 99,4 % | ≥ 99,9 % | Despliegue sin corte; healthchecks; múltiples instancias | 3 |
Tres observaciones sobre estos objetivos que conviene interiorizar:
1. Ninguno persigue la etiqueta "elite". Reservalia no se ha propuesto desplegar veinte veces al día. Se ha propuesto cinco veces por semana, que para ellos es una transformación radical y, sobre todo, alcanzable. Un objetivo que el equipo no cree posible no motiva: desmoraliza.
2. Los objetivos son del equipo, no de personas. Es "el lead time de Reservalia", no "el lead time de Diego". Volveremos sobre esto ahora mismo.
3. Van acompañados de la palanca concreta. Una métrica sin una acción asociada es un termómetro sin medicina. Cada objetivo apunta al módulo donde se trabaja.
graph LR
subgraph HOY["📍 Punto de partida"]
H1["1,1 despliegues/semana"]
H2["6,2 días de lead time"]
H3["14 % de fallos"]
H4["68 min de restauración"]
end
subgraph MOD["🔧 El curso"]
M2["Módulo 2<br/>CI: pruebas y artefactos"]
M3["Módulo 3<br/>CD: despliegue y rollback"]
M4["Módulo 4<br/>Optimización y seguridad"]
end
subgraph META["🎯 Objetivo"]
O1["≥5 despliegues/semana"]
O2["<4 h de lead time"]
O3["<5 % de fallos"]
O4["<10 min de restauración"]
end
HOY --> MOD --> META
style HOY fill:#ffe8e8
style META fill:#e8ffe8
- La ley de Goodhart: cuando la métrica se convierte en objetivo
Hay una forma infalible de destruir el valor de todo lo anterior, y es tan común que merece su propia sección.
Ley de Goodhart: "Cuando una medida se convierte en objetivo, deja de ser una buena medida."
El mecanismo es siempre el mismo: si de una métrica dependen la evaluación de desempeño, el bonus o el prestigio de alguien, esa persona optimizará la métrica —que es más fácil que optimizar la realidad que la métrica pretendía representar.
12.1. Cómo se manipula cada métrica DORA
| Métrica | Si se convierte en objetivo individual… | Consecuencia real |
|---|---|---|
| Frecuencia de despliegue | Se trocean cambios artificialmente en diez despliegues vacíos; se despliega el mismo código dos veces | El número sube, no llega más valor al usuario, y el ruido dificulta diagnosticar incidentes |
| Lead time | Se hacen commits justo antes de fusionar para "resetear" el reloj; se trabaja en local semanas sin commitear | El dato mejora y el tiempo real de entrega empeora, porque las ramas viven más |
| Change failure rate | Se reclasifican incidentes como "mantenimiento programado"; se deja de registrar lo dudoso | Los datos dejan de ser reales y se pierde la capacidad de detectar problemas |
| Time to restore | Se declara el servicio restablecido antes de que lo esté; se retrasa la apertura del incidente | Los usuarios siguen sufriendo y el panel está verde |
Fíjate en el caso del lead time: es especialmente perverso porque la manipulación empeora activamente el proceso. El desarrollador que evita commitear para no "empezar el reloj" está haciendo justo lo contrario de la Integración Continua.
12.2. Reglas para usar las métricas sin destruirlas
- Nunca a nivel individual. Son métricas de sistema, no de persona. "El lead time del equipo de Reservalia", jamás "el lead time de Diego". El lead time depende de la velocidad de las revisiones, del proceso de aprobación, de la duración del pipeline y de la ventana de despliegue: casi nada de eso está bajo el control de una sola persona.
- Nunca para comparar equipos. Un equipo que mantiene un legacy crítico tendrá siempre peores números que uno que empieza un producto nuevo, y eso no dice nada sobre su competencia. Cada equipo se compara consigo mismo.
- Nunca ligadas a retribución o evaluación. Es el camino más corto a datos falsos. En cuanto el bonus depende del número, el número deja de describir la realidad.
- Siempre las cuatro juntas. Es la protección estructural. Trocear despliegues para subir la frecuencia empeora el change failure rate; no commitear para bajar el lead time reduce la frecuencia. Mirando las cuatro, las manipulaciones se delatan.
- Como herramienta de diagnóstico, no de juicio. El uso correcto es: "nuestro lead time es de 6 días; vamos a averiguar dónde se va el tiempo". El incorrecto es: "nuestro lead time es de 6 días; hay que mejorarlo este trimestre", sin analizar la causa.
- Mira la tendencia, no el valor absoluto. Una lectura aislada no dice casi nada. Doce semanas de datos dicen mucho.
12.3. Un antídoto práctico
Cuando presentes las métricas, acompáñalas siempre de la pregunta "¿qué nos impide mejorar esto?" en lugar de "¿por qué está mal esto?". La primera abre una conversación técnica y produce acciones; la segunda produce excusas y, a medio plazo, datos manipulados.
Errores Comunes y Consejos
Error 1: medir el lead time desde que arranca el pipeline. Es el error más frecuente y el que más engaña, porque produce números excelentes. Mide desde la fecha del commit; si no, ocultas justamente el tiempo de espera, que suele ser el problema principal.
Error 2: usar la media en vez de la mediana. Un cambio que se quedó dos meses en una rama olvidada distorsiona la media por completo. La mediana describe el caso típico. Añade el percentil 90 si quieres saber cómo de malo es el peor caso habitual.
Error 3: contar los despliegues a staging. Solo cuenta lo que llega a los usuarios. Es una forma tentadora de inflar la frecuencia de despliegue sin que llegue más valor a nadie.
Error 4: no acordar por escrito qué es un "fallo". Sin una definición explícita en el repositorio, cada persona clasificará los casos dudosos a su manera y la métrica dejará de ser comparable en el tiempo. Acordadla antes de empezar a medir.
Error 5: perseguir la etiqueta "elite". Los umbrales cambian cada año y dependen del contexto. La única comparación que importa es contigo mismo hace tres meses.
Error 6: montar el cuadro de mando antes de tener el pipeline. Es tentador empezar por lo visual. Pero sin despliegues automatizados no hay eventos que registrar, y acabarás rellenando datos a mano, que es exactamente donde se generan los datos falsos. Registra primero, visualiza después.
Error 7: medir sin tener línea base. Si empiezas a medir después de automatizar, no podrás demostrar la mejora. Reconstruir el trimestre anterior a partir del historial de Git y las notas de incidencias, como hizo Marta, es una tarde de trabajo bien invertida.
Consejo 1: registra el evento de despliegue desde el primer pipeline. Es una tabla y una consulta INSERT al final del job. Cinco minutos de trabajo que, seis meses después, valen una conversación entera con dirección.
Consejo 2: guarda el SHA y la fecha del commit en el propio artefacto. Etiquetar la imagen con el SHA y añadir la fecha como etiqueta de metadatos hace que el artefacto sea autodescriptivo: siempre podrás saber qué versión es y cuándo se escribió, aunque la rama ya no exista.
Consejo 3: revisa las métricas en equipo, una vez al mes, sin dirección delante. El objetivo de la reunión es identificar cuellos de botella, no rendir cuentas. En cuanto se percibe como una evaluación, los datos empiezan a degradarse.
Consejo 4: complementa las cuatro con algo cualitativo. Una pregunta trimestral al equipo —"del 1 al 5, ¿cuánta confianza tienes al desplegar a producción?"— captura algo que ninguna de las cuatro mide y que suele anticipar los problemas antes de que aparezcan en los números.
Ejercicios
Ejercicio 1: calcular las cuatro métricas
Estos son los datos reales del último mes de otra empresa, Citalia. Calcula sus cuatro métricas DORA y clasifícalas orientativamente.
Despliegues a producción (mes de marzo, 30 días):
| ID | Commit | Fecha del commit | Fecha del despliegue | ¿Provocó fallo? |
|---|---|---|---|---|
| d1 | aaa1111 |
2026-03-02 09:00 | 2026-03-05 17:00 | No |
| d2 | bbb2222 |
2026-03-04 14:00 | 2026-03-05 17:00 | No |
| d3 | ccc3333 |
2026-03-06 11:00 | 2026-03-12 17:00 | Sí |
| d4 | ddd4444 |
2026-03-12 18:00 | 2026-03-12 19:30 | No (corrección urgente) |
| d5 | eee5555 |
2026-03-10 10:00 | 2026-03-19 17:00 | No |
| d6 | fff6666 |
2026-03-18 16:00 | 2026-03-19 17:00 | No |
| d7 | ggg7777 |
2026-03-20 09:00 | 2026-03-26 17:00 | Sí |
| d8 | hhh8888 |
2026-03-26 18:00 | 2026-03-26 20:00 | No (corrección urgente) |
Incidentes:
| ID | Inicio (empezó a afectar) | Detectado | Restablecido |
|---|---|---|---|
| i1 | 2026-03-12 17:20 | 2026-03-12 18:05 | 2026-03-12 19:35 |
| i2 | 2026-03-26 17:10 | 2026-03-26 17:25 | 2026-03-26 20:05 |
Calcula: frecuencia de despliegue (por semana), lead time mediano (en horas), change failure rate y time to restore mediano. Después, responde: ¿qué patrón revelan estos datos sobre cómo trabaja Citalia?
Ejercicio 2: detectar manipulación de métricas
El nuevo director de tecnología de Citalia ha establecido que el bonus trimestral de cada desarrollador dependerá de "su" lead time individual y de "su" frecuencia de despliegue. Tres meses después, el panel muestra:
- Frecuencia de despliegue: de 1,9 a 11,3 por semana. 🎉
- Lead time mediano: de 4,1 días a 3,2 horas. 🎉
- Change failure rate: de 25 % a 31 %. 😐
- Time to restore mediano: de 145 min a 210 min. 😟
- Los desarrolladores comentan que ahora hacen la mayor parte del trabajo en local y solo commitean al final.
- El número medio de commits por despliegue ha bajado de 4,2 a 1,1, pero el número de líneas cambiadas por despliegue no ha bajado.
Responde:
- ¿Han mejorado de verdad? Justifica con los datos.
- ¿Qué comportamiento concreto explica cada cifra?
- ¿Cuál es el dato que delata la manipulación de forma más clara?
- ¿Qué habrías hecho en lugar de ligar el bonus a las métricas?
Ejercicio 3: instrumentar Reservalia
Diseña la instrumentación mínima para que Reservalia empiece a medir hoy, antes de tener ningún pipeline.
- ¿Qué eventos hay que registrar como mínimo y en qué momento exacto de cada proceso?
- Escribe la consulta SQL que dé el lead time mediano en horas de las últimas 8 semanas para el servicio
apien producción. - Reservalia despliega
apiywebjuntas en el mismo acto. ¿Debe registrarse como un despliegue o como dos? Argumenta las dos posturas y decide. - El primer mes solo habrá unos 5 despliegues. ¿Qué precaución hay que tomar al interpretar las métricas con tan pocos datos?
Soluciones
Solución al Ejercicio 1
Frecuencia de despliegue
→ Nivel medio (entre una vez al mes y una vez a la semana, rozando el alto).
Lead time por despliegue
| ID | Commit | Despliegue | Lead time |
|---|---|---|---|
| d1 | 03-02 09:00 | 03-05 17:00 | 80 h |
| d2 | 03-04 14:00 | 03-05 17:00 | 27 h |
| d3 | 03-06 11:00 | 03-12 17:00 | 150 h |
| d4 | 03-12 18:00 | 03-12 19:30 | 1,5 h |
| d5 | 03-10 10:00 | 03-19 17:00 | 223 h |
| d6 | 03-18 16:00 | 03-19 17:00 | 25 h |
| d7 | 03-20 09:00 | 03-26 17:00 | 152 h |
| d8 | 03-26 18:00 | 03-26 20:00 | 2 h |
Ordenados: 1,5 · 2 · 25 · 27 · 80 · 150 · 152 · 223
Con 8 valores, la mediana es la media de los dos centrales (4.º y 5.º):
→ Nivel alto (entre un día y una semana).
Compara con la media: (1,5+2+25+27+80+150+152+223) / 8 = 82,6 h. Un 55 % más alta, arrastrada por los dos valores extremos. Esto ilustra por qué se usa la mediana.
Change failure rate
→ Nivel medio.
Nota importante: d4 y d8 son las correcciones urgentes, no los fallos. No se cuentan como fallidos —ellos arreglaron el problema—, pero sí cuentan en el denominador como despliegues realizados. Contarlos también como fallidos duplicaría el problema en la métrica.
Time to restore service
i1: 03-12 19:35 − 03-12 17:20 = 135 minutos
i2: 03-26 20:05 − 03-26 17:10 = 175 minutos
mediana = (135 + 175) / 2 = 155 minutos ≈ 2,6 horas→ Nivel alto (menos de un día).
Un detalle que había que notar: la columna "Detectado" no se usa. El tiempo se cuenta desde que el incidente empieza a afectar a los usuarios. Si se midiera desde la detección, i1 daría 90 minutos en vez de 135 —y Citalia estaría premiándose por tener mala monitorización.
¿Qué patrón revelan los datos?
Un patrón muy claro y muy reconocible:
- Despliegan los jueves a las 17:00. d1, d2, d3, d5, d6 y d7 son todos jueves a las 17:00. Tienen una ventana de despliegue semanal, exactamente el mismo antipatrón que Reservalia con sus viernes.
- El 25 % de sus despliegues son correcciones urgentes (d4 y d8), y ambas ocurren el mismo día que un despliegue fallido, pocas horas después. Es decir: la ventana semanal genera lotes grandes, los lotes grandes rompen producción, y hay que salir de urgencia fuera de la ventana.
- La ventana es la causa del lead time alto. Fíjate en el contraste: los despliegues dentro de la ventana tienen lead times de 25 a 223 horas; las correcciones urgentes, de 1,5 y 2 horas. Técnicamente pueden desplegar en 90 minutos. El resto del tiempo es espera pura, autoimpuesta por el proceso.
- Los dos incidentes son consecuencia de despliegues. Su problema no es la infraestructura: es cómo entregan.
Conclusión del diagnóstico: la palanca de mejora número uno de Citalia no es comprar herramientas ni escribir más tests. Es eliminar la ventana semanal de los jueves. Ese único cambio atacaría a la vez el lead time, el tamaño del lote y el change failure rate.
Solución al Ejercicio 2
1. ¿Han mejorado de verdad?
No. Han mejorado las dos métricas de velocidad (las que afectan al bonus) y han empeorado las dos de estabilidad (las que no). Ese patrón exacto —velocidad arriba, estabilidad abajo— es la firma clásica de la manipulación, y es justamente lo que el conjunto de cuatro métricas está diseñado para revelar.
Recuerda el hallazgo central de la sección 1: en una mejora real, velocidad y estabilidad mejoran juntas. Cuando divergen en direcciones opuestas, no estás viendo una mejora: estás viendo cómo se optimiza el indicador a costa de lo que el indicador debía representar.
2. Qué comportamiento explica cada cifra
| Cifra | Comportamiento que la produce |
|---|---|
| Frecuencia ×6 | Se trocean los cambios en despliegues artificiales para que cada desarrollador acumule despliegues propios |
| Lead time de 4,1 días a 3,2 h | Se trabaja en local durante días y se commitea justo antes de fusionar: el reloj empieza tarde. El tiempo real de entrega no ha bajado; solo ha bajado la parte que se mide |
| Change failure rate 25 % → 31 % | Más despliegues sin más verificación; y, sobre todo, código que ha estado días sin integrarse (integration hell de 01-01) llega de golpe |
| Time to restore 145 → 210 min | Con más despliegues fragmentados y menos integración, diagnosticar qué rompió qué es más difícil. Además, nadie tiene incentivo en restaurar rápido: no puntúa |
3. El dato que delata la manipulación
El número de commits por despliegue baja de 4,2 a 1,1 mientras las líneas cambiadas por despliegue se mantienen.
Este dato es demoledor y merece pararse en él. Si los lotes fueran realmente más pequeños, ambas cifras habrían bajado: menos commits y menos líneas por despliegue. Que las líneas no bajen significa que se está entregando la misma cantidad de cambio, empaquetada en menos commits. Es decir: la gente acumula trabajo en local y lo suelta en un único commit gigante justo antes de fusionar.
Eso es exactamente lo contrario de la Integración Continua, y explica de forma coherente las cuatro cifras a la vez: ramas más longevas → integración más tardía → más conflictos y menos verificación → más fallos → diagnósticos más lentos.
4. Qué habría que haber hecho
- No ligar nunca las métricas a la retribución ni a la evaluación individual. Es la regla que se ha roto y de la que se deriva todo lo demás.
- Medir a nivel de equipo o de servicio, nunca de persona. El lead time depende de la velocidad de las revisiones, de los procesos de aprobación y de la ventana de despliegue: casi nada de eso lo controla un individuo.
- Usar las métricas para diagnosticar, no para juzgar. El análisis del ejercicio 1 mostraba que el problema de Citalia era la ventana semanal de los jueves. La acción correcta era eliminarla, no repartir bonus.
- Presentar siempre las cuatro juntas. Si el panel del director hubiera mostrado las cuatro desde el principio, la divergencia habría saltado a la vista en la primera revisión mensual.
- Fijar objetivos de sistema, no de persona. "Reducir el lead time del equipo por debajo de 8 horas eliminando la ventana de despliegue" es un objetivo accionable y compartido. "Que cada desarrollador baje su lead time" no lo es.
Solución al Ejercicio 3
1. Eventos mínimos y momento exacto
| Evento | Cuándo se registra exactamente | Campos imprescindibles |
|---|---|---|
| Despliegue a producción | Como último paso del proceso de despliegue, solo si ha terminado con éxito | id, servicio, entorno, commit_sha, commit_fecha, desplegado_en, commits_incluidos |
| Marca de despliegue fallido | Durante el incidente, en cuanto se identifica el despliegue culpable | despliegue_id, fallido = true, motivo |
| Apertura de incidente | Cuando se determina la hora en que empezó a afectar a los usuarios (no la de detección) | id, servicio, inicio, severidad, despliegue_id si aplica |
| Cierre de incidente | Cuando el servicio vuelve a funcionar para los usuarios (no cuando se entiende la causa) | restablecido |
Detalle crítico: commit_fecha debe capturarse en el momento del despliegue con git show -s --format=%cI, no consultarse después. Las ramas se borran y los historiales se reescriben.
Mientras no exista pipeline, estos eventos se registran a mano con un script de dos líneas ejecutado por quien despliega. No es elegante, pero produce datos reales desde hoy, que es lo que importa.
2. Consulta SQL
SELECT
ROUND(
PERCENTILE_CONT(0.5) WITHIN GROUP (
ORDER BY EXTRACT(EPOCH FROM (desplegado_en - commit_fecha))
) / 3600.0, 1
) AS lead_time_mediana_horas,
COUNT(*) AS n_despliegues -- imprescindible para saber si el dato vale
FROM despliegues
WHERE servicio = 'api'
AND entorno = 'prod'
AND resultado = 'exito'
AND desplegado_en >= now() - interval '8 weeks';El COUNT(*) no es opcional: una mediana calculada sobre 5 despliegues no debe presentarse igual que una calculada sobre 200.
3. ¿Un despliegue o dos?
A favor de registrarlo como dos (uno por servicio):
- Es lo que recomienda el marco DORA: la unidad de medida es el servicio desplegable.
- Permite ver si un servicio evoluciona distinto del otro (por ejemplo, si la web se despliega más a menudo cuando se independicen).
- Si en el futuro se separan —cosa muy probable—, la serie histórica sigue siendo comparable.
A favor de registrarlo como uno:
- Refleja la realidad actual: hoy no se pueden desplegar por separado, así que dos filas sugieren una independencia que no existe.
- Duplicaría artificialmente la frecuencia de despliegue, haciendo que Reservalia parezca el doble de rápida de lo que es.
Decisión: registrar dos filas, una por servicio, pero con un campo grupo_despliegue común que las vincule. Así se conserva la granularidad por servicio para el futuro y, a la vez, se puede calcular la frecuencia contando grupos distintos en lugar de filas, sin inflar el número. Es la opción que no destruye información y que no engaña.
-- Frecuencia REAL de despliegue (actos de despliegue, no filas)
SELECT COUNT(DISTINCT grupo_despliegue) FROM despliegues
WHERE entorno = 'prod' AND resultado = 'exito';4. Precauciones con pocos datos
- Con 5 despliegues, la mediana es muy inestable. Un solo valor extremo la desplaza por completo. No tomes decisiones basándote en la variación de un mes a otro.
- El change failure rate es especialmente engañoso. Con 5 despliegues, cada fallo vale un 20 %: pasar de 0 % a 20 % suena a catástrofe y es un solo incidente. Con estos volúmenes, es más informativo reportar el número absoluto ("1 de 5") que el porcentaje.
- Usa ventanas más largas. Con poco volumen, agrega por trimestre en lugar de por semana, o usa medias móviles de 90 días.
- Muestra siempre el tamaño de la muestra junto a cada métrica. Un panel que dice "change failure rate: 20 %" sin decir "(1 de 5)" invita a conclusiones equivocadas.
- Fíjate en la tendencia, no en el valor puntual. Con pocos datos, la dirección del movimiento a lo largo de varios meses es mucho más fiable que cualquier cifra concreta.
- Y algo tranquilizador: a medida que Reservalia avance en el curso, la frecuencia de despliegue subirá, y con ella el volumen de datos. Las métricas se vuelven más fiables precisamente a medida que el proceso mejora.
Conclusión
Con esta lección cerramos el módulo de introducción, y lo hacemos con lo que probablemente sea la herramienta más práctica de todo el módulo:
- Las cuatro métricas DORA —frecuencia de despliegue, lead time for changes, change failure rate y time to restore service— resumen el rendimiento de la entrega en dos parejas que se equilibran: velocidad y estabilidad. Su gran virtud es que no se pueden manipular a la vez.
- El hallazgo que cambia la forma de pensar: velocidad y estabilidad van juntas. Desplegar más a menudo obliga a lotes pequeños, y los lotes pequeños fallan menos y se diagnostican antes.
- La quinta métrica, la fiabilidad, mide el resultado operativo mediante objetivos de nivel de servicio propios de cada equipo, y evita el espejismo de tener las cuatro en verde con un servicio malo.
- Cada dato sale de un evento concreto: la frecuencia y el lead time, del job de despliegue y de la fecha del commit; el change failure rate, de una marca humana durante el incidente; el time to restore, de la gestión del incidente. Todo cabe en dos tablas y unas pocas consultas SQL: no hace falta comprar nada.
- Los rangos de rendimiento son referencias que se mueven cada año y dependen del contexto. La única comparación que importa es contigo mismo hace tres meses.
- Reservalia ya tiene su línea base medida: 1,1 despliegues por semana, 6,2 días de lead time, 14 % de cambios fallidos y 68 minutos de restauración. Y sus objetivos para el final del curso: 5 despliegues semanales, menos de 4 horas, menos del 5 % y menos de 10 minutos.
- Y la advertencia que sostiene todo lo demás: la ley de Goodhart. En cuanto una métrica se convierte en objetivo individual —ligado a evaluaciones o bonus—, deja de describir la realidad. Son métricas de sistema, sirven para diagnosticar, y se miran las cuatro juntas.
Con esto termina el módulo 1. Ya sabes qué son la Integración Continua, la Entrega Continua y el Despliegue Continuo y en qué se diferencian; conoces los beneficios reales y los costes que nadie menciona; tienes el mapa del ecosistema de herramientas y sabes por qué usaremos GitHub Actions; conoces a fondo Reservalia, su equipo, su repositorio y su infraestructura de destino; y tienes el cuadro de mando que nos dirá, dentro de siete módulos, si todo esto ha servido de algo.
Se acabó la teoría. En el módulo 2, Integración Continua (CI), empezamos a construir: la primera lección, Introducción a la Integración Continua, sienta las reglas de trabajo del equipo —qué es la rama principal, cuánto puede vivir una rama, qué pasa cuando la build se pone roja— y en la lección 02-02 escribiremos, por fin, el primer workflow real de Reservalia. Diego dejará de compilar en su portátil: a partir de ahí, cada cambio se verifica solo, en una máquina limpia, antes de que nadie lo fusione.
Curso de CI/CD: Integración y Despliegue Continuo
Módulo 1: Introducción a CI/CD
- Conceptos Básicos de CI/CD
- Beneficios de CI/CD
- Herramientas Populares de CI/CD
- El Proyecto del Curso: la Aplicación que Vamos a Automatizar
- Métricas DORA: Cómo se Mide la Entrega de Software
Módulo 2: Integración Continua (CI)
- Introducción a la Integración Continua
- Configuración de un Entorno de CI
- Automatización de la Construcción
- Pruebas Automatizadas
- Calidad de Código y Análisis Estático
- Artefactos, Versionado y Promoción
- Integración con Control de Versiones
Módulo 3: Despliegue Continuo (CD)
- Introducción al Despliegue Continuo
- Automatización del Despliegue
- Infraestructura como Código y Entornos Reproducibles
- Estrategias de Despliegue
- Feature Flags, Rollback y Recuperación ante Fallos
- Monitoreo y Retroalimentación
Módulo 4: Prácticas Avanzadas de CI/CD
- Pipelines de CI/CD
- Gestión de Dependencias
- Seguridad en CI/CD
- Escalabilidad y Rendimiento
- Pipeline as Code: Plantillas, Reutilización y Pruebas del Pipeline
- Bases de Datos en el Pipeline: Migraciones Seguras
Módulo 5: Implementación de CI/CD en Proyectos Reales
- Caso de Estudio: Proyecto Web
- Caso de Estudio: Aplicación Móvil
- Caso de Estudio: Microservicios
- Caso de Estudio: Modernizar un Proyecto Legacy
Módulo 6: Herramientas y Tecnologías
- Jenkins
- GitLab CI/CD
- CircleCI
- Travis CI
- Docker y Kubernetes
- GitHub Actions a Fondo
- Comparativa y Criterios para Elegir Herramienta
Módulo 7: Ejercicios Prácticos
- Ejercicio 1: Configuración de un Pipeline Básico
- Ejercicio 2: Integración de Pruebas Automatizadas
- Ejercicio 3: Despliegue en un Entorno de Producción
- Ejercicio 4: Monitoreo y Retroalimentación
- Ejercicio 5: Endurecer el Pipeline con Seguridad y Secretos
- Proyecto Final: Pipeline Completo de Extremo a Extremo
