Módulo 2: Slis Slos And The Error Budget
5. Eligiendo un SLO que signifique algo
Descripción
La lección 4 midió el tráfico real de process-shipment-manifest contra un SLO de referencia, 99,9%, y encontró un presupuesto casi agotado (4,23 de 43,2 minutos). Esa cifra no es una propiedad fija del sistema — es el resultado de comparar el mismo desempeño real contra un número específico que alguien eligió. Esta lección hace la pregunta que la lección 3 del Módulo 1 ya planteó en teoría, ahora con la calculadora real: ¿qué le pasa a esa misma lectura si el SLO elegido fuera distinto? La respuesta, corrida tres veces sobre exactamente los mismos datos, es la demostración más directa de por qué el SLO no es un detalle técnico —es una decisión con consecuencias medibles, inmediatas, sobre cuánto margen de error tiene un equipo.
Conexión con el módulo
Nada en esta lección cambia el dataset de la lección 4 ni la definición de SLI de la lección 3 — el desempeño real de process-shipment-manifest durante esos 30 días fue el que fue, un solo hecho. Lo único que varía es el SLO, el parámetro que ya viste que budget_report acepta sin tocar el resto del código (Módulo 2, lección 4, ejercicio 3). Esta lección corre esa función tres veces, con tres SLOs, y deja que los números —no una opinión— muestren por qué "elige el SLO más alto posible" (el error más común que el Módulo 1, lección 3, ya nombró) es, en los hechos, una forma de convertir un mes tranquilo en una crisis fabricada.
La tabla de nueves, recordada del Módulo 1
Ya viste esta tabla en la lección 3 del Módulo 1, con la cita exacta de Google SRE sobre por qué el costo de cada nueve adicional crece de forma no lineal. Vale la pena tenerla enfrente antes de correr la calculadora:
| SLO | Indisponibilidad permitida / mes (30 días) | Lo que suele costar llegar ahí |
|---|---|---|
| 99% ("dos nueves") | ~7,3 horas (432 minutos) | Redundancia básica, reinicio manual aceptable |
| 99,9% ("tres nueves") | ~43,2 minutos | Automatización de recuperación, monitoreo activo |
| 99,99% ("cuatro nueves") | ~4,3 minutos | Redundancia multi-zona, failover automático, on-call serio |
Esta lección no repite la teoría de esa tabla — la corre contra datos reales, para que el salto entre filas deje de ser una abstracción de "cuesta más" y se convierta en un número concreto de minutos de margen, medido sobre el mismo mes que ya conoces.
Corriendo la calculadora, tres veces, sin cambiar el dataset
Usando exactamente TRAFFIC_30_DAYS de la lección 4 —el mismo tráfico real, el mismo SLI medido de 99,9098%— la única línea que cambia es el argumento slo:
from error_budget_calculator import TRAFFIC_30_DAYS, budget_report, print_report
for slo in [0.99, 0.999, 0.9999]:
report = budget_report(TRAFFIC_30_DAYS, slo=slo)
print_report(report, f"SLO {slo:.2%}")
print()
Qué esperar (literal — el SLI medido, 99,9098%, es idéntico en las tres corridas; lo único que cambia es el SLO):
--- SLO 99.00% ---
Eventos validos: 12195
Eventos buenos: 12184
SLI medido: 99.9098%
SLO objetivo: 99.0%
Presupuesto (mensual): 432.0 minutos
Consumido en el periodo: 38.97 minutos (9.0% del presupuesto)
Presupuesto restante: 393.03 minutos
--- SLO 99.90% ---
Eventos validos: 12195
Eventos buenos: 12184
SLI medido: 99.9098%
SLO objetivo: 99.9%
Presupuesto (mensual): 43.2 minutos
Consumido en el periodo: 38.97 minutos (90.2% del presupuesto)
Presupuesto restante: 4.23 minutos
--- SLO 99.99% ---
Eventos validos: 12195
Eventos buenos: 12184
SLI medido: 99.9098%
SLO objetivo: 100.0%
Presupuesto (mensual): 4.3 minutos
Consumido en el periodo: 38.97 minutos (902.0% del presupuesto)
Presupuesto restante: -34.65 minutos
(El SLO de 99,99% se imprime como 100.0% porque print_report redondea a un decimal — el valor real usado en el cálculo, sin redondear, sigue siendo 99,99%; el ejercicio 1 de esta lección vuelve sobre este detalle.)
El mismo mes, tres historias completamente distintas
Este es el resultado central de la lección, y vale la pena leerlo con calma porque es contraintuitivo la primera vez que se ve con números reales: process-shipment-manifest tuvo exactamente el mismo desempeño los 30 días —los mismos 11 errores, sobre las mismas 12.195 invocaciones válidas, el mismo SLI de 99,9098%— y sin embargo:
- A 99%, ese mes fue tranquilo: 9,0% del presupuesto consumido, 393 minutos de margen. Un equipo con este SLO podría lanzar experimentos arriesgados el resto del mes sin preocuparse.
- A 99,9%, ese mismo mes estuvo al borde: 90,2% consumido, apenas 4,23 minutos de margen. Un equipo con este SLO debería estar en alerta, revisando qué causó los errores de los días 17-18 antes de arriesgar nada más.
- A 99,99%, ese mismo mes fue, sin ambigüedad, un fracaso: 902% del presupuesto consumido, un déficit de 34,65 minutos. Un equipo con este SLO ya agotó, varias veces, cualquier margen — y lo agotó desde antes del día 17, porque un presupuesto de 4,3 minutos se hubiera consumido con muchísimo menos que los 11 errores reales de este dataset.
Ninguna de las tres lecturas es "incorrecta" — la aritmética de las tres es perfecta. Lo que cambia es si el número que sale de esa aritmética significa algo útil para el negocio que decidió el SLO. Elegir 99,99% para process-shipment-manifest no habría hecho que el sistema fuera más confiable de verdad —el desempeño real fue el mismo en los tres escenarios—; solo habría convertido cada mes normal en una "crisis" según el papel, entrenando al equipo a ignorar alertas porque disparan todo el tiempo, exactamente el problema de "umbral que grita demasiado" que el Módulo 4 de esta guía va a resolver con burn rate.
Entonces, ¿qué SLO tiene sentido para Andes Cargo?
Esta lección no cierra esa pregunta todavía —eso es, formalmente, el trabajo de la lección 8, con SLO.md— pero ya deja evidencia suficiente para orientar la decisión: process-shipment-manifest es, según RELIABILITY-CHARTER.md (Módulo 1, lección 8, posición 2 de la sección Decision), "not a payments system or a life-support system" — un procesador asíncrono de manifiestos, donde el costo real de unos minutos de indisponibilidad adicional es bajo. Con esa evidencia de negocio, más el resultado de esta lección —a 99,9% el sistema real está genuinamente cerca del límite, ni trivialmente cómodo ni catastróficamente roto—, el candidato más defendible entre los tres escenarios corridos es 99,9%: es el único de los tres donde el número tiene margen para significar algo —queda cerca de cero pero no negativo, así que un mes ligeramente peor sí importaría, y un mes ligeramente mejor sí se notaría—. La lección 8 retoma esta evidencia, junto con la de burn rate de la lección 6, para fijar la decisión final en SLO.md.
Errores comunes
Elegir 99,99% porque "el sistema debería aspirar a lo mejor posible" (el mismo error de la lección 3 del Módulo 1, reaparecido con números reales). Qué pasa: alguien, viendo la tabla de nueves, asume que apuntar más alto siempre es la decisión más responsable. Cómo detectarlo: si tu justificación para un SLO alto no incluye ningún argumento sobre qué le costaría al negocio no alcanzarlo. Cómo corregirlo: esta lección ya lo mostró con números —el mismo desempeño real que "aprueba cómodo" a 99% "reprueba por casi 35 minutos" a 99,99%. Un SLO no es una aspiración, es un objetivo que el sistema debe poder cumplir de forma sostenida con el diseño y el presupuesto de ingeniería que realmente tiene.
Interpretar el 902% de la corrida a 99,99% como un error del script (de desconfiar de un número extremo). Qué pasa: alguien ve "902.0% del presupuesto" y "-34.65 minutos" y asume que hay un bug en budget_report. Cómo detectarlo: si tu primera reacción a un porcentaje mayor a 100% es "esto no puede ser correcto". Cómo corregirlo: un presupuesto puede consumirse más del 100% —significa, literalmente, que el sistema gastó más minutos de indisponibilidad de los que el SLO permitía, y el déficit (los minutos negativos) es exactamente esa cantidad—. No hay ningún límite matemático que impida que minutes_consumed supere a budget_minutes; el límite que sí existe es de diseño: un SLO tan estricto que el sistema real lo incumple por un margen tan grande, la mayoría de los meses, no es un SLO útil.
Tratar el "candidato" de 99,9% de esta lección como la decisión final ya cerrada (de anticipar la lección 8). Qué pasa: alguien, al terminar esta lección, escribe en SLO.md que el SLO de Andes Cargo es 99,9%, dando por resuelta la lección 8 antes de tiempo. Cómo detectarlo: si ya citas "el SLO de Andes Cargo" como un hecho fijado antes de llegar a la lección 8 de este módulo. Cómo corregirlo: esta lección reúne evidencia —tres escenarios corridos, uno de ellos claramente más defendible— pero la lección 6 todavía tiene que sumar la perspectiva de burn rate, que puede reforzar o matizar esta elección antes de que SLO.md la fije con su justificación completa.
Ejercicios
Ejercicio 1 — Explica por qué print_report mostró 100.0% para un SLO de 99,99%, y por qué eso no afecta el resultado del cálculo. ¿Qué parte exacta del código produce ese redondeo, y qué pasaría si quisieras mostrar más precisión?
Ver solución
La línea responsable es print(f"SLO objetivo: {report['slo']:.1%}") dentro de print_report — el especificador de formato .1% redondea a un solo decimal al convertir a porcentaje, y 99,99% redondeado a un decimal es, en efecto, 100,0%. El valor real almacenado en report['slo'] sigue siendo 0.9999 sin ningún redondeo —la prueba está en que budget_minutes se calculó correctamente como 4,3 minutos, que es (1 - 0.9999) × 43200, no (1 - 1.0) × 43200 (que daría cero)—. Para mostrar más precisión bastaría con cambiar el especificador de formato a .2% o .3% en esa única línea de print_report, sin tocar ningún cálculo.
Ejercicio 2 — Calcula, sin ejecutar nada, cuántos errores adicionales (sobre los 11 reales) habrían bastado para que el escenario de 99,9% también terminara con presupuesto negativo. Usa los números ya calculados en esta lección.
Ver solución
El presupuesto restante a 99,9% es 4,23 minutos. Cada evento malo adicional, aplicado sobre 12.195 eventos válidos, agrega una tasa de error de 1/12.195 ≈ 0,0082%, que sobre la ventana de 43.200 minutos representa 0,0082% × 43.200 ≈ 3,54 minutos consumidos adicionales. Con solo 2 errores más (13 en vez de 11), el consumo adicional sería de aproximadamente 7,08 minutos — más que suficiente para agotar los 4,23 minutos restantes y dejar el presupuesto en negativo. Esto confirma, con aritmética simple, lo cerca que estuvo este mes real de un déficit: no hicieron falta 11 errores más, ni siquiera 5 — con apenas 2 invocaciones malas adicionales en todo el mes, el SLO de 99,9% también se hubiera incumplido.
Ejercicio 3 — Argumenta, usando el resultado de esta lección, por qué un SLO no debería elegirse mirando solo la tabla de nueves del Módulo 1, sin datos reales de tráfico. ¿Qué le faltaba a esa tabla que esta lección sí aporta?
Ver solución
La tabla de nueves del Módulo 1 muestra cuántos minutos de indisponibilidad permite cada SLO —información necesaria, pero abstracta: nunca dice si el sistema real es capaz de cumplir esa cifra—. Un ingeniero que solo mirara esa tabla podría razonar "43,2 minutos suena como un margen cómodo" sin ninguna evidencia de si el sistema real, con su tasa de error histórica, se queda cerca de ese límite o lejos de él. Esta lección aporta exactamente lo que faltaba: el mismo tráfico real, corrido contra tres SLOs distintos, mostrando que 43,2 minutos (99,9%) no es "cómodo" en absoluto para este sistema específico —es apenas suficiente, con solo 4,23 minutos de margen—. Elegir un SLO sin este paso sería exactamente el error que RELIABILITY-CHARTER.md ya rechazó en el Módulo 1: un número elegido "porque suena responsable", sin la evidencia de si el sistema real puede sostenerlo.
Resumen y siguiente paso
En esta lección corriste la misma calculadora, sobre el mismo tráfico real de 30 días, con tres SLOs distintos: a 99% el mes fue cómodo (393 minutos de margen); a 99,9% estuvo al borde (4,23 minutos); a 99,99% fue un fracaso claro (déficit de 34,65 minutos). El mismo desempeño real, leído con tres varas distintas, contó tres historias completamente diferentes — la demostración más directa de por qué el SLO es una decisión con consecuencias medibles, no un detalle que se elige por instinto. Con esa evidencia, identificaste 99,9% como el candidato más defendible para Andes Cargo, sin cerrar todavía la decisión final.
Antes de avanzar deberías poder: correr la calculadora contra al menos tres SLOs distintos y explicar la diferencia en los tres resultados; calcular a mano cuántos errores adicionales habrían llevado un escenario de presupuesto positivo a uno negativo; y explicar por qué la tabla de nueves del Módulo 1, sola, no basta para elegir un SLO real.
La lección 6 agrega la pieza que esta lección todavía no tiene: no solo cuánto presupuesto queda al final del mes, sino qué tan rápido se estuvo gastando en cada momento — burn rate, la fórmula de sre.google/workbook/alerting-on-slos/, aplicada al mismo dataset que ya conoces.
Recursos
- Este mismo repositorio, Módulo 1, lección 3 (
03-reliability-as-a-feature-not-an-accident.md) — la tabla de nueves y la cita de Google SRE sobre el costo no lineal de cada nueve adicional. - Este mismo repositorio, Módulo 1, lección 8 (
08-project-andes-cargos-reliability-charter.md) —RELIABILITY-CHARTER.md, posición 2 de la sección Decision, la evidencia de negocio que orienta el candidato de SLO de esta lección. - Google SRE Book, Capítulo 3 — Embracing Risk — la fuente original del costo no lineal de la confiabilidad, ya citada en el Módulo 1.
- Este mismo repositorio, Módulo 2, lección 4 (
04-hands-on-the-error-budget-calculator.md) — el dataset y la funciónbudget_reportque esta lección reutiliza sin modificar.