05 — SLO, SLI, SLA et error budgets
Ce que tu vas apprendre
- Les définitions exactes de SLI, SLO et SLA — et leurs différences
- Comment calculer un error budget à partir d'un SLO
- Les SLI concrets à mesurer pour une API REST
- Les requêtes PromQL pour mesurer le respect d'un SLO
- Pourquoi l'error budget change la relation entre fiabilité et vitesse de déploiement
Prérequis
Les définitions
SLI — Service Level Indicator
Un SLI est une métrique qui mesure un aspect du comportement d'un service du point de vue de l'utilisateur. C'est une fraction : événements bons / événements totaux.
SLI disponibilité = requêtes réussies / requêtes totales
SLI latence = requêtes en dessous de 200ms / requêtes totales
SLI fraîcheur = données mises à jour dans les 5 dernières minutes / données totales
SLO — Service Level Objective
Un SLO est l'objectif que tu te fixes sur un SLI, sur une fenêtre de temps.
SLO disponibilité : 99,9% des requêtes réussissent sur 30 jours
SLO latence : 95% des requêtes répondent en moins de 200ms sur 30 jours
SLA — Service Level Agreement
Un SLA est un contrat avec des conséquences (pénalités financières, remboursements) si le SLO n'est pas respecté. Il est toujours moins exigeant que le SLO interne.
SLA externe : 99,5% de disponibilité (avec pénalités si non respecté)
SLO interne : 99,9% (marge de sécurité de 0,4%)
| SLI | SLO | SLA |
|---|---|---|
| Ce qu'on mesure | L'objectif qu'on se fixe | Le contrat externe |
L'error budget
L'error budget est le montant d'indisponibilité autorisé par le SLO sur la fenêtre de temps.
SLO = 99,9% sur 30 jours
Error budget = 100% - 99,9% = 0,1%
= 0,1% × 30 jours × 24h × 60min
= 43,8 minutes de downtime autorisé par mois
| SLO | Error budget / mois |
|---|---|
| 99% | 7h 18min |
| 99,5% | 3h 39min |
| 99,9% | 43min 48s |
| 99,95% | 21min 54s |
| 99,99% | 4min 22s |
Ce que l'error budget change :
Si l'error budget est entier (pas d'incident ce mois) → les équipes peuvent déployer rapidement, expérimenter, prendre des risques.
Si l'error budget est consommé → gel des déploiements non critiques jusqu'à la fin de la fenêtre.
"Error budgets are the key mechanism for making the tradeoff between reliability and velocity explicit." — Beyer et al., Site Reliability Engineering (2016), Chapitre 4
SLI concrets pour une API REST
Disponibilité
promql# SLI disponibilité = requêtes réussies (2xx, 3xx) / total
# Les 4xx sont des erreurs client — normalement exclus du SLI serveur
sum(rate(http_requests_total{status=~"2..|3.."}[5m]))
/
sum(rate(http_requests_total[5m]))
Latence
promql# SLI latence = requêtes sous 200ms / total
# Nécessite un histogram avec bucket à 0.2
sum(rate(http_request_duration_seconds_bucket{le="0.2"}[5m]))
/
sum(rate(http_request_duration_seconds_count[5m]))
Fraîcheur (pour les APIs de données)
promql# SLI fraîcheur = données mises à jour dans les 5 dernières minutes
# Nécessite une gauge "dernière mise à jour"
time() - data_last_updated_timestamp_seconds < 300
Mesurer le respect du SLO sur 30 jours
La difficulté : un taux de succès sur 5 minutes ne dit rien sur les 30 jours. Il faut une fenêtre glissante.
Méthode 1 : Recording rules Prometheus
yaml# prometheus-rules.yml
groups:
- name: slo-rules
interval: 30s
rules:
# Taux de succès sur 1h (pour les alertes court-terme)
- record: job:sli_availability:ratio_rate1h
expr: |
sum(rate(http_requests_total{status=~"2..|3.."}[1h]))
/
sum(rate(http_requests_total[1h]))
# Taux de succès sur 30 jours (pour le SLO)
- record: job:sli_availability:ratio_rate30d
expr: |
sum(rate(http_requests_total{status=~"2..|3.."}[30d]))
/
sum(rate(http_requests_total[30d]))
- name: slo-alerts
rules:
# Alerte si le SLI 1h tombe sous 99% (burn rate élevé)
- alert: SLOAvailabilityBurnRate
expr: job:sli_availability:ratio_rate1h < 0.99
for: 5m
labels:
severity: warning
annotations:
summary: "SLI disponibilité sous 99% depuis 5 minutes"
description: "Taux actuel : {{ $value | humanizePercentage }}"
Méthode 2 : Burn rate alerting
Le burn rate mesure à quelle vitesse tu consommes l'error budget. Un burn rate de 1 = tu consommes exactement au rythme prévu pour atteindre 0 à la fin de la fenêtre. Un burn rate de 10 = tu épuises le budget 10 fois trop vite.
promql# Burn rate sur 1h
# SLO = 99,9% → error rate budget = 0,1%
# Si error rate actuel = 1% → burn rate = 1% / 0,1% = 10
(1 - job:sli_availability:ratio_rate1h) / (1 - 0.999)
Alertes multi-fenêtres (recommandation Google SRE):
| Fenêtre courte | Fenêtre longue | Burn rate | Sévérité | Action |
|---|---|---|---|---|
| 5min | 1h | > 14,4× | Page immédiate | Incident critique |
| 30min | 6h | > 6× | Page | Incident |
| 2h | 1 jour | > 3× | Ticket | Investigation |
| 6h | 3 jours | > 1× | Info | Monitoring |
yaml# Alert page immédiate : burn rate > 14,4 sur 5min ET 1h
- alert: SLOHighBurnRate
expr: |
(1 - job:sli_availability:ratio_rate5m) / (1 - 0.999) > 14.4
AND
(1 - job:sli_availability:ratio_rate1h) / (1 - 0.999) > 14.4
labels:
severity: critical
annotations:
summary: "Burn rate critique — error budget épuisé en < 1h"
Choisir les bons SLO
Ce qu'il ne faut pas faire
- 100% de disponibilité — impossible en pratique, et un SLO à 100% interdit tout déploiement
- SLO sans SLI mesurable — "le service est rapide" n'est pas un SLO
- Trop de SLOs — se concentrer sur 2-3 SLIs par service
Ce qu'il faut faire
Partir des besoins utilisateurs (critical user journey) :
Service de paiement :
SLI 1 : disponibilité (requêtes réussies / total) → SLO 99,95%
SLI 2 : latence p99 < 1s → SLO 99%
API de catalogue (lecture seule) :
SLI 1 : disponibilité → SLO 99,9%
SLI 2 : latence p95 < 100ms → SLO 99%
Worker de traitement de commandes :
SLI 1 : fraîcheur (commandes traitées dans les 10min) → SLO 99,5%
SLI 2 : taux d'erreur de traitement < 0,1% → SLO 99,9%
Implémentation simple en TypeScript
typescript// slo-calculator.ts
interface SLOConfig {
name: string;
target: number; // Ex: 0.999 pour 99,9%
windowDays: number; // Ex: 30
}
interface SLOStatus {
currentSLI: number;
errorBudgetTotal: number; // En secondes
errorBudgetConsumed: number; // En secondes
errorBudgetRemaining: number; // En secondes
burnRate: number;
isBreaching: boolean;
}
function calculateSLOStatus(
config: SLOConfig,
currentSLI: number
): SLOStatus {
const windowSeconds = config.windowDays * 24 * 60 * 60;
const errorBudgetTotal = (1 - config.target) * windowSeconds;
const errorBudgetConsumed = (1 - currentSLI) * windowSeconds;
const burnRate = (1 - currentSLI) / (1 - config.target);
return {
currentSLI,
errorBudgetTotal,
errorBudgetConsumed,
errorBudgetRemaining: errorBudgetTotal - errorBudgetConsumed,
burnRate,
isBreaching: currentSLI < config.target,
};
}
// Exemple
const status = calculateSLOStatus(
{ name: "api-availability", target: 0.999, windowDays: 30 },
0.997 // SLI actuel : 99,7%
);
console.log(`Error budget restant : ${(status.errorBudgetRemaining / 60).toFixed(1)} minutes`);
// Error budget restant : -17.3 minutes ← SLO violé
Résumé
| Concept | Définition | Exemple |
|---|---|---|
| SLI | Métrique utilisateur (fraction) | 99,7% de requêtes réussies |
| SLO | Objectif sur le SLI | 99,9% sur 30 jours |
| SLA | Contrat externe | 99,5% avec pénalités |
| Error budget | Marge d'indisponibilité autorisée | 43min 48s / mois |
| Burn rate | Vitesse de consommation du budget | > 1 = trop vite |
Étape suivante : 06 — Alerting — construire des alertes actionnables sans créer du bruit.
Sources
- Beyer, B., et al. (2016). Site Reliability Engineering, Chapitres 4 "Service Level Objectives" et 5 "Eliminating Toil". O'Reilly. sre.google/sre-book/service-level-objectives/
- Beyer, B., et al. (2018). The Site Reliability Workbook, Chapitre 2 "Implementing SLOs". O'Reilly. sre.google/workbook/implementing-slos/
- Prometheus Authors. Recording Rules. prometheus.io/docs/prometheus/latest/configuration/recording_rules/
- Slater, A. (2020). Multi-window, multi-burn-rate alerts. Google Cloud Blog.