Les postmortems d'incidents représentent l'une des pratiques les plus précieuses pour améliorer la fiabilité. Correctement exécuté, un postmortem transforme chaque incident en opportunité d'apprentissage.
Mal conduit, il dégénère en exercice de blame qui décourage la transparence.
Qu'est-ce qu'un Postmortem d'Incident ?
Un postmortem est un processus d'analyse structurée conduit après la résolution d'un incident significatif. Son objectif n'est pas d'attribuer des responsabilités mais de comprendre les facteurs qui ont permis à l'incident de survenir.
Le terme "blameless"
Le terme blameless postmortem souligne l'orientation constructive plutôt que punitive. L'objectif est de renforcer les défenses du système, pas de punir les individus.
Les composantes d'un postmortem
Un postmortem efficace examine l'incident sous plusieurs angles :
- Chronologie factuelle : déroulement précis des événements
- Analyse d'impact : conséquences pour les utilisateurs et l'entreprise
- Analyse causale : facteurs contributifs à tous les niveaux
- Action items : mesures correctives avec responsables et échéances
Pourquoi les Postmortems sont Essentiels
Prévention de la récurrence
Sans analyse approfondie, les mêmes combinaisons de facteurs produiront les mêmes incidents.
Incidents similaires sans postmortem:
Janvier: 4h d'indisponibilité
Mars: 3h d'indisponibilité
Juin: 5h d'indisponibilité
Avec postmortem et actions:
Janvier: 4h d'indisponibilité
→ Postmortem + actions
Plus aucun incident similaire
Les études montrent une réduction de 40% de la récurrence avec des postmortems systématiques.
Partage des apprentissages
Un incident dans une équipe peut révéler des vulnérabilités présentes dans d'autres systèmes :
- Diffusion des postmortems à travers l'organisation
- Apprentissage des erreurs des autres
- Détection précoce de patterns similaires
Culture de sécurité psychologique
Des postmortems blameless encouragent la transparence :
Amélioration de la documentation
Chaque postmortem enrichit la base de connaissances :
- Comportement des systèmes
- Modes de défaillance
- Procédures de résolution efficaces
Comment Conduire un Postmortem Efficace
Phase 1 : Préparation
Collectez exhaustivement les données avant la réunion :
# Checklist de collecte
□ Logs applicatifs (période incident + 1h avant/après)
□ Métriques de monitoring
□ Captures d'écran des dashboards
□ Historique des communications (Slack, emails)
□ Historique des déploiements récents
□ Changements d'infrastructure
□ Timeline préliminaire
Identifiez tous les participants impliqués dans la détection, gestion ou résolution.
Phase 2 : Réunion de postmortem
Organisez la réunion dans un délai de 2 à 5 jours après l'incident :
| Timing | Avantage | Risque |
|---|---|---|
| Trop tôt (< 2j) | Souvenirs frais | Émotions pas apaisées |
| Optimal (2-5j) | Équilibre | - |
| Trop tard (> 7j) | - | Détails oubliés |
Un facilitateur neutre guide la discussion et garantit un ton constructif.
Phase 3 : Analyse causale
Utilisez la technique des 5 pourquoi pour remonter aux causes racines :
Symptôme: Le site était indisponible pendant 2 heures
Pourquoi? → Le serveur web a crashé
Pourquoi? → La mémoire était saturée
Pourquoi? → Une fuite mémoire dans le nouveau code
Pourquoi? → Pas de tests de performance avant déploiement
Pourquoi? → Les tests de perf ne sont pas dans le pipeline CI
Cause racine: Absence de tests de performance automatisés
Explorez les facteurs à tous les niveaux :
- Technique : bug, configuration, infrastructure
- Processuel : procédures, documentation, communication
- Organisationnel : pression, ressources, formation
Phase 4 : Rédaction du document
Structurez le document pour qu'il soit compréhensible par quelqu'un qui n'a pas participé :
# Postmortem: Indisponibilité API Payment - 2024-01-15
## Résumé
- **Durée**: 2h15 (14:30 - 16:45 UTC)
- **Impact**: 100% des transactions échouées, ~15,000 utilisateurs affectés
- **Sévérité**: SEV1
- **Détection**: Alerte automatique (latence > 5s)
## Timeline
| Heure | Événement |
|-------|-----------|
| 14:28 | Déploiement v2.3.1 |
| 14:30 | Première alerte latence |
| 14:35 | IC désigné, investigation commence |
| 14:52 | Cause identifiée: query N+1 |
| 15:10 | Rollback initié |
| 15:25 | Rollback échoue (migration DB) |
| 16:30 | Hotfix déployé |
| 16:45 | Service restauré |
## Analyse des causes
### Cause directe
Query N+1 introduite dans le nouveau code, générant 100x plus de requêtes DB.
### Facteurs contributifs
1. Revue de code n'a pas détecté le pattern
2. Pas de test de charge avant déploiement
3. Rollback bloqué par migration irréversible
## Actions
| Action | Propriétaire | Échéance | Priorité |
|--------|--------------|----------|----------|
| Ajouter linter N+1 queries | @dev-lead | 2024-01-22 | P1 |
| Tests de charge obligatoires | @sre-team | 2024-01-29 | P1 |
| Réviser stratégie migrations | @db-team | 2024-02-05 | P2 |
Phase 5 : Suivi des actions
Chaque action doit avoir :
- Un propriétaire identifié
- Une échéance réaliste
- Un critère de complétion vérifiable
# Exemple de suivi structuré
action_items:
- id: PM-2024-01-15-001
title: "Ajouter linter N+1 queries au CI"
owner: "@dev-lead"
due_date: "2024-01-22"
status: "in_progress"
completion_criteria: "Linter bloque les PR avec patterns N+1"
related_pr: "https://github.com/org/repo/pull/1234"
Bonnes Pratiques pour les Postmortems
Approche blameless rigoureuse
Concentrez-vous sur les systèmes, pas sur les individus :
Documenter les near-misses
Les situations qui auraient pu mal tourner recèlent les mêmes enseignements :
near_miss_report:
date: "2024-01-10"
description: "Certificat SSL expirant dans 3 jours détecté par hasard"
potential_impact: "Indisponibilité complète du site"
prevention: "Alerte automatique 30 jours avant expiration"
Suivi systématique des actions
Intégrez le suivi dans vos rituels d'équipe :
## Weekly Team Meeting - Postmortem Actions
### Actions en retard
- PM-2024-01-15-001: Linter N+1 (retard 3 jours) - @dev-lead
### Actions complétées cette semaine
- PM-2024-01-08-003: Monitoring connexions DB ✓
### Prochaines échéances
- PM-2024-01-15-002: Tests de charge (due 2024-01-29)
Base de données recherchable
Rendez les postmortems accessibles et indexés :
-- Rechercher des postmortems similaires
SELECT title, date, summary, actions
FROM postmortems
WHERE
full_text_search @@ to_tsquery('memory & leak')
OR tags @> ARRAY['memory', 'performance']
ORDER BY date DESC
LIMIT 10;
Célébrer la transparence
Reconnaissez publiquement les équipes qui produisent des postmortems instructifs :
Comparaison des Formats de Postmortem
Plusieurs organisations ont popularisé des formats différents. Voici comment ils se comparent :
| Aspect | Google SRE | PagerDuty | Atlassian | Custom (Notre Template) |
|---|---|---|---|---|
| Origine | Livre SRE de Google (2016) | Documentation incident response PagerDuty | Atlassian Incident Handbook | Adapté des meilleures pratiques du secteur |
| Approche blameless | Principe central — section dédiée | Forte — intégrée au processus | Modérée — mentionnée sans être centrale | Forte — intégrée dans chaque section |
| Format timeline | Log chronologique détaillé | Structuré par phases détection/réponse | Timeline simplifiée | Détaillé avec attribution des sources |
| Méthode d'analyse | Récit narratif du "que s'est-il passé" | 5 Pourquoi encouragés | Diagrammes fishbone / Ishikawa | Flexible — 5 Pourquoi ou narratif |
| Métriques d'impact | Minutes-utilisateurs, consommation d'error budget | Impact business | Suivi SLA/SLO | Revenu, utilisateurs, SLA combinés |
| Suivi des actions | Références bugs/tickets | Intégré aux workflows PagerDuty | Liaison avec Jira | Tableau propriétaire + échéance + priorité |
| Réunion de revue | Obligatoire — revue formelle avec parties prenantes | Recommandée — compatible asynchrone | Obligatoire — rétrospective d'équipe | Recommandée sous 48h |
| Forces | Éprouvé à grande échelle, excellente structure narrative | Bien intégré aux workflows d'alerting | Familier pour les équipes Jira | Complet, prêt à copier, adaptable |
| Faiblesses | Peut être lourd pour les petits incidents | Lié à l'écosystème PagerDuty | Moins prescriptif sur le blameless | Demande de la discipline pour remplir |
| Idéal pour | Grandes organisations SRE | Équipes utilisant déjà PagerDuty | Écosystème Atlassian | Équipes cherchant un template autonome |
Template de Postmortem
Voici un template complet à adapter :
# Postmortem: [Titre descriptif]
# Date: [AAAA-MM-JJ]
## Métadonnées
- **Sévérité**: [SEV1 / SEV2 / SEV3 / SEV4]
- **Durée**: [Heure début] — [Heure fin] ([X]h [Y]min)
- **Auteur**: [Nom]
- **Date du postmortem**: [AAAA-MM-JJ]
- **Statut**: [Brouillon / En revue / Final]
- **Participants**: [Liste des noms]
## Résumé exécutif
[2-3 phrases : ce qui s'est passé, combien de temps, qui a été affecté,
comment c'a été résolu.]
## Impact
- **Utilisateurs affectés**: [Nombre ou pourcentage]
- **Requêtes / transactions échouées**: [Nombre]
- **Perte de revenu estimée**: [X €]
- **SLA/SLO violés**: [Oui/Non — préciser lesquels]
- **Tickets support ouverts**: [Nombre]
- **Communication publique envoyée**: [Oui/Non]
## Timeline (UTC)
| Heure | Événement | Source |
|-------|-----------|--------|
| HH:MM | [Premier signe du problème] | [Monitoring / Signalement client / Log de déploiement] |
| HH:MM | [Alerte déclenchée] | [PagerDuty / Grafana / Datadog] |
| HH:MM | [Incident déclaré — IC assigné] | [Slack / Outil d'incident] |
| HH:MM | [Investigation démarrée] | [Intervenant] |
| HH:MM | [Cause racine identifiée] | [Intervenant] |
| HH:MM | [Correction appliquée] | [Intervenant] |
| HH:MM | [Service restauré] | [Monitoring] |
| HH:MM | [Incident clos] | [IC] |
## Détection
- **Comment l'incident a-t-il été détecté ?** [Alerte / Signalement client / Observation interne]
- **Temps de détection (TTD)**: [X minutes]
- **Les alertes existantes étaient-elles efficaces ?** [Oui/Non — expliquer]
## Cause racine
[Explication technique détaillée de ce qui a causé l'incident. Soyez précis
sur le mécanisme de défaillance, pas seulement sur le symptôme.]
## Facteurs contributifs
1. [Facteur 1 — ex. couverture de tests manquante sur un cas limite]
2. [Facteur 2 — ex. pas de circuit breaker sur la dépendance aval]
3. [Facteur 3 — ex. runbook obsolète]
## Ce qui a bien fonctionné
- [Positif 1 — ex. alerte déclenchée en moins de 2 minutes]
- [Positif 2 — ex. coordination efficace dans le canal d'incident]
- [Positif 3 — ex. procédure de rollback fonctionnelle]
## Ce qui a mal fonctionné
- [Négatif 1 — ex. 30 min pour identifier la cause racine]
- [Négatif 2 — ex. pas de runbook pour ce mode de défaillance]
## Actions correctives
| ID | Action | Propriétaire | Échéance | Priorité | Statut |
|----|--------|--------------|----------|----------|--------|
| 1 | [Action spécifique et mesurable] | @responsable | AAAA-MM-JJ | P1 | Ouvert |
| 2 | [Action spécifique et mesurable] | @responsable | AAAA-MM-JJ | P2 | Ouvert |
| 3 | [Action spécifique et mesurable] | @responsable | AAAA-MM-JJ | P2 | Ouvert |
## Leçons apprises
- [Enseignement clé 1]
- [Enseignement clé 2]
## Annexes
- [Lien vers snapshot Grafana]
- [Lien vers thread Slack]
- [Lien vers log de déploiement]
Exemple concret : Saturation du Pool de Connexions Base de Données
Voici un postmortem rempli basé sur un incident de production réaliste (mais fictif). Utilisez-le comme référence pour rédiger les vôtres.
# Postmortem: Saturation du Pool de Connexions PostgreSQL
# Date: 2026-02-12
## Métadonnées
- **Sévérité**: SEV1
- **Durée**: 09:47 — 11:32 UTC (1h 45min)
- **Auteur**: Sarah Chen (SRE)
- **Date du postmortem**: 2026-02-14
- **Statut**: Final
- **Participants**: Sarah Chen, Marco Rossi, Priya Patel, James O'Brien
## Résumé exécutif
Une requête lente introduite dans le déploiement v4.12.0 a provoqué la
saturation du pool de connexions PostgreSQL primaire en 20 minutes. Toutes
les endpoints API ont retourné des erreurs 503 pendant 1 heure et 45 minutes,
affectant 100% des utilisateurs. Le service a été restauré par rollback
du déploiement et application d'un index d'urgence.
## Impact
- **Utilisateurs affectés**: 42 000 (100% des utilisateurs actifs)
- **Requêtes échouées**: 1,2 million d'appels API en 503
- **Perte de revenu estimée**: 35 000 €
- **SLA/SLO violés**: Oui — SLO de disponibilité mensuel (99,9%) consommé
- **Tickets support ouverts**: 312
- **Communication publique envoyée**: Oui — page de statut mise à jour à 10:05 UTC
## Timeline (UTC)
| Heure | Événement | Source |
|-------|-----------|--------|
| 09:32 | Déploiement v4.12.0 en production | ArgoCD |
| 09:47 | Utilisation du pool de connexions dépasse le seuil de 80% | Alerte Grafana |
| 09:48 | Alerte PagerDuty — Marco Rossi acquitte | PagerDuty |
| 09:52 | Premières erreurs 503 détectées par monitoring externe | WizStatus |
| 09:55 | Incident déclaré SEV1 — Sarah Chen assignée IC | Slack |
| 10:05 | Page de statut mise à jour — investigation en cours | StatusPage |
| 10:12 | Corrélation avec le déploiement v4.12.0 identifiée | Investigation |
| 10:18 | Requête lente identifiée : nouvel endpoint scanne table de 4M lignes | pg_stat |
| 10:25 | Rollback vers v4.11.3 initié | ArgoCD |
| 10:41 | Rollback terminé — pool toujours en vidange (requêtes longues) | Grafana |
| 10:55 | DBA termine manuellement les requêtes bloquées | psql |
| 11:02 | Pool de connexions revenu à des niveaux normaux | Grafana |
| 11:15 | Santé API confirmée sur toutes les régions | WizStatus |
| 11:32 | Incident clos | Slack |
## Détection
- **Comment l'incident a-t-il été détecté ?** Alerte automatique sur pool > 80%
- **Temps de détection (TTD)**: 15 minutes après le déploiement
- **Les alertes existantes étaient-elles efficaces ?** Partiellement — l'alerte
sur le pool s'est déclenchée mais il n'y avait pas d'alerte sur le p99 de
durée des requêtes, qui aurait déclenché 5 min plus tôt
## Cause racine
La version v4.12.0 a introduit un nouvel endpoint `/api/reports/export` qui
exécutait un full table scan sur la table `transactions` (4,2M lignes) sans
index sur les colonnes de filtre `(account_id, created_at)`. Chaque requête
monopolisait une connexion pendant 12 à 45 secondes au lieu des 50ms
habituelles. Avec un trafic normal de ~200 requêtes/min sur cet endpoint,
le pool de 50 connexions était épuisé en 20 minutes.
## Facteurs contributifs
1. **Pas de revue de requêtes en CI** — La requête générée par l'ORM n'a pas
été analysée pour les index manquants avant le merge
2. **Pas de timeout par requête** — Les connexions DB n'avaient pas de
statement timeout, permettant aux requêtes de 45s de bloquer indéfiniment
3. **Volume de données staging inadéquat** — Le staging n'avait que 12 000
lignes dans `transactions`, rendant le scan rapide en pré-production
4. **Rollback retardé de 15 min** — L'équipe a d'abord investigué avant de
décider le rollback
## Ce qui a bien fonctionné
- Alerte sur le pool de connexions déclenchée en 15 min après le déploiement
- Incident commander assigné rapidement (3 min après la première alerte)
- Page de statut mise à jour dans les 10 min suivant la déclaration
- Équipe a identifié la requête responsable en 23 min
## Ce qui a mal fonctionné
- 15 minutes passées à investiguer avant de tenter le rollback
- Pas de gate de performance des requêtes en CI
- Les requêtes longues bloquées ont nécessité une intervention DBA manuelle
- L'environnement de staging n'a pas révélé le problème
## Actions correctives
| ID | Action | Propriétaire | Échéance | Priorité | Statut |
|----|--------|--------------|----------|----------|--------|
| 1 | Ajouter `statement_timeout = 5s` à la config DB applicative | @marco | 2026-02-19 | P1 | Fait |
| 2 | Ajouter un check CI pour requêtes sans index sur tables > 100K lignes | @priya | 2026-02-26 | P1 | En cours |
| 3 | Alimenter le staging `transactions` avec un volume production (4M lignes) | @james | 2026-03-05 | P2 | Ouvert |
| 4 | Ajouter alerte p99 durée requêtes (> 2s déclenche warning) | @sarah | 2026-02-21 | P1 | Fait |
| 5 | Documenter la politique "rollback d'abord" pour les incidents de pool | @sarah | 2026-02-21 | P2 | Fait |
| 6 | Ajouter métrique et alerte sur la profondeur de queue du pool | @marco | 2026-03-05 | P2 | Ouvert |
## Leçons apprises
- Le rollback doit être l'action par défaut pour les incidents de pool de
connexions ; investiguer pendant que le pool est saturé prolonge la panne
- Les requêtes générées par l'ORM peuvent masquer des problèmes de performance
qui n'apparaissent qu'avec les volumes de données de production
- Les statement timeouts sont un filet de sécurité critique — sans eux, un
seul type de requête lente peut provoquer une panne totale en cascade
## Annexes
- [Dashboard Grafana pool de connexions](https://grafana.internal/d/pg-pool)
- [Thread Slack incident](https://slack.com/archives/C0123/p1707731700)
- [Log de déploiement ArgoCD v4.12.0](https://argocd.internal/app/api/v4.12.0)
Conclusion
Les postmortems blameless transforment les incidents douloureux en apprentissages précieux.
En établissant un processus structuré, en maintenant une culture de sécurité psychologique et en suivant rigoureusement les actions, vous créez une boucle d'amélioration continue.
N'attendez pas le prochain incident majeur pour instaurer cette pratique. Commencez dès maintenant avec les incidents mineurs pour affiner votre processus.
WizStatus vous fournit les données détaillées de monitoring essentielles à la reconstruction précise de la timeline lors de vos postmortems.
Guides connexes
- Gestion des Incidents IT — Établissez le processus d'incident qui alimente vos postmortems
- Configurer une Rotation d'Astreinte — Définissez la structure d'astreinte qui intervient en premier
- Automatisation des Runbooks — Automatisez les actions correctives identifiées dans les postmortems
- Calculateur du Coût des Temps d'Arrêt — Quantifiez l'impact métier documenté dans vos postmortems