Aller au contenu
Documentation medium

Architecture Decision Records (ADR) : tracer vos choix

30 min de lecture

Un ADR (Architecture Decision Record) est un document court, 1 à 2 pages, qui capture une décision technique importante, son contexte et ses conséquences. La pratique tient en trois règles : une décision par fichier, un fichier immuable une fois accepté, et un rangement à côté du code, dans docs/adr/NNNN-titre.md. Le format le plus répandu est MADR (Markdown Any Decision Records). On écrit un ADR pour tout choix coûteux à défaire : base de données, framework, broker de messages, langage, protocole, découpage en services. Cette page explique à quoi sert un ADR, quand en écrire, comment remplir le template MADR, comment intégrer la pratique dans une équipe et quels anti-patterns la font mourir. Pour développeurs, architectes et tech leads qui veulent arrêter de perdre la mémoire de leurs choix.

  • Définir ce qu'est un ADR et le distinguer de la documentation classique.
  • Décider quand écrire un ADR (et quand ce n'est pas la peine).
  • Utiliser le template MADR pour structurer une décision.
  • Intégrer la pratique ADR dans le workflow d'équipe sans friction.
  • Éviter les anti-patterns classiques (ADR trop tard, trop long, oublié).

Le scénario suivant se rejoue dans beaucoup d'organisations, avec des noms de technologies différents. Une banque européenne, en 2019 : un développeur senior découvre dans le code une architecture microservices de 47 services communiquant via RabbitMQ. Personne dans l'équipe actuelle ne sait pourquoi ce choix a été fait trois ans plus tôt. L'architecte d'origine est parti. Les spécifications techniques sont muettes sur ce point.

L'équipe passe 6 mois à investiguer avant de comprendre que RabbitMQ avait été choisi pour sa capacité de dead-letter queues, essentielle pour la conformité réglementaire. Sans cette connaissance, ils étaient sur le point de migrer vers Kafka, une décision qui aurait violé les exigences de la régulation bancaire.

Un simple ADR de 2 pages aurait évité ces 6 mois perdus.

Un Architecture Decision Record (ADR) est un document court qui capture une décision architecturale significative, son contexte et ses conséquences. Le concept a été formalisé par Michael Nygard en novembre 2011 dans son article fondateur « Documenting Architecture Decisions ».

Nygard, également auteur de l'ouvrage « Release It! », part d'un constat de terrain : « personne ne lit les gros documents d'architecture, mais ne pas connaître les raisons derrière les décisions architecturales importantes peut mener à des conséquences désastreuses ». Tout le format en découle. Un ADR est court pour être lu, il est daté pour situer le contexte de l'époque, et il conserve les options écartées parce que c'est cette information, et non la solution retenue, qui manque au lecteur trois ans plus tard.

AspectDocumentation classiqueADR
LongueurDes dizaines de pages1-2 pages maximum
PortéeSystème completUne seule décision
Mise à jourRare (souvent obsolète)Immutable (on crée un nouvel ADR)
Question« Comment ça marche ? »« Pourquoi ce choix ? »
AudienceNouveaux arrivantsFuturs décideurs
Durée de vieCourte (devient obsolète)Permanente (historique)

La documentation classique explique l'état actuel. Les ADR expliquent le chemin parcouru.

Un dépôt Git conserve ce qui a été fait, jamais pourquoi. Le raisonnement, les options écartées et les contraintes du moment vivent dans la mémoire de ceux qui étaient présents, et disparaissent avec eux.

Les décisions architecturales ont une caractéristique particulière : elles sont faciles à oublier mais coûteuses à redécouvrir.

Scénario typique :

  1. Un architecte fait un choix technique important
  2. Il en parle en réunion, envoie un email
  3. 18 mois plus tard, il quitte l'entreprise
  4. Un nouveau développeur se demande « pourquoi PostgreSQL et pas MongoDB ? »
  5. Personne ne se souvient, l'email est introuvable
  6. L'équipe passe des semaines à analyser, benchmarker
  7. Ils prennent une décision... peut-être la même, peut-être différente
  8. Le cycle recommence

Le gain principal d'un ADR n'est pas documentaire, il est temporel : il supprime le travail d'enquête que représente la redécouverte d'un choix passé. Ces quatre effets apparaissent dès quelques dizaines d'ADR accumulés dans un dépôt.

BénéficeCe qui change concrètement
Onboarding accéléréL'arrivant lit dix décisions datées au lieu d'interroger cinq personnes
Décisions plus rapidesLes options déjà évaluées ne sont pas ré-analysées depuis zéro
Moins de « pourquoi ? »Les interruptions des développeurs seniors se raréfient
Audit facilitéLa traçabilité des choix est disponible sans reconstitution

Ces bénéfices se chiffrent mal, et les pourcentages qui circulent sur le sujet sont rarement sourcés. Une chose se mesure en revanche sans difficulté dans votre propre équipe : le délai de réponse à la question « pourquoi ce composant est-il là ? ». Chronométrez-le avant d'adopter les ADR, puis un an plus tard, sur trois ou quatre composants tirés au hasard.

Un ADR efficace suit une structure standardisée. Le template le plus populaire est MADR (Markdown Architectural Decision Records), mais le template original de Michael Nygard reste une référence.

Structure d'un ADR avec les sections contexte, options, décision et conséquences

Le template original est minimaliste, c'est sa force :

docs/adr/0001-record-architecture-decisions.md
# 1. Record architecture decisions
Date: 2024-01-15
## Status
Accepted
## Context
We need to record the architectural decisions made on this project.
## Decision
We will use Architecture Decision Records, as described by Michael Nygard.
## Consequences
See Michael Nygard's article, linked above. For a lightweight ADR toolset,
see Nat Pryce's adr-tools.

Ce format compte quatre sections (Status, Context, Decision, Consequences), précédées d'un titre numéroté et d'une date. Ces six éléments suffisent à rendre une décision compréhensible des années plus tard.

  1. Titre : numéroté, action claire (« Use X for Y »)
  2. Date : quand la décision a été prise
  3. Status : Proposed, Accepted, Deprecated ou Superseded
  4. Context : pourquoi cette décision est nécessaire
  5. Decision : ce qui a été décidé
  6. Consequences : impacts positifs et négatifs

MADR (Markdown Any Decision Records) reprend le squelette de Nygard et y ajoute trois sections qui manquent dès que la décision est disputée : Decision Drivers, Options considérées et Liens. Les decision drivers sont les critères de choix, écrits avant de comparer les options : ce sont eux qui empêchent la comparaison d'être rédigée après coup pour justifier une préférence. La section Options considérées conserve les branches non prises, avec leurs avantages, ce qui évite de les réévaluer plus tard. La section Liens rattache l'ADR aux autres, par Supersedes et Superseded by, et constitue le fil de l'historique.

L'exemple ci-dessous est complet : il se lit du haut vers le bas comme le raisonnement s'est déroulé, du problème aux conséquences négatives assumées.

docs/adr/0042-use-postgresql-for-main-database.md
# ADR-0042 : Utiliser PostgreSQL comme base de données principale
## Statut
Accepted
## Contexte et problème
Notre application a besoin d'une base de données relationnelle capable de :
- Gérer des transactions ACID complexes
- Stocker des données JSON semi-structurées
- Supporter 10 000 requêtes/seconde en lecture
L'équipe a des compétences MySQL et MongoDB, mais pas PostgreSQL.
## Decision Drivers
* Performance en lecture intensive
* Support JSON natif sans sacrifier les jointures SQL
* Coût de licence (open-source préféré)
* Maturité de l'écosystème (tooling, monitoring)
* Courbe d'apprentissage pour l'équipe
## Options considérées
### Option 1 : MySQL 8.x
**Avantages** :
- Équipe déjà formée
- Large communauté
**Inconvénients** :
- Support JSON moins mature que PostgreSQL
- Performances JSON inférieures dans nos benchmarks
### Option 2 : PostgreSQL 16
**Avantages** :
- Excellent support JSON (JSONB indexable)
- Performances supérieures dans nos tests (+30%)
- Extensions riches (PostGIS, TimescaleDB)
**Inconvénients** :
- Formation équipe nécessaire (2-3 semaines)
- Certains outils internes à adapter
### Option 3 : MongoDB 7.x
**Avantages** :
- Flexibilité schéma
- Équipe partiellement formée
**Inconvénients** :
- Pas de transactions multi-documents fiables
- Coût plus élevé à grande échelle
## Décision
**Nous choisissons PostgreSQL 16** pour toutes les nouvelles applications.
Raisons principales :
1. Les benchmarks montrent +30% de performance sur nos cas d'usage
2. Le support JSONB permet de mixer relationnel et document
3. L'écosystème d'extensions répond à nos besoins futurs (géospatial, time-series)
## Conséquences
### Positives
* Performance garantie pour nos cas d'usage
* Base technologique pérenne (PostgreSQL en croissance)
* Possibilité d'utiliser des extensions avancées
### Négatives
* Investissement formation : 3 semaines pour l'équipe
* Migration des outils internes : 2 sprints estimés
* Besoin de recruter un DBA avec expertise PostgreSQL
### Neutres
* Les applications MySQL existantes restent sur MySQL
* Revue dans 12 mois pour valider les hypothèses de performance
## Liens
* Supersedes: ADR-0023 (Use MySQL for all databases)
* Benchmarks: /docs/benchmarks/database-comparison-2024.md
* RFC associée: /docs/rfc/0015-database-strategy.md

Un ADR n'est pas un document figé, il évolue selon un cycle de vie défini :

Cycle de vie d'un ADR : Proposed, Accepted, Deprecated ou Superseded

Un ADR porte toujours l'un de ces quatre statuts : Proposed, Accepted, Deprecated ou Superseded. Les deux premiers décrivent une décision vivante, les deux derniers une décision sortie du jeu, avec une nuance qui compte : Deprecated signifie que le sujet a disparu, Superseded que la question s'est reposée et a reçu une autre réponse. Chaque onglet montre le bloc ## Status correspondant, avec les métadonnées à y faire figurer.

Proposed : la décision est en cours de discussion.

L'ADR est rédigé mais pas encore validé. C'est le moment des revues, des commentaires, des ajustements.

## Status
Proposed
Reviewers: @alice, @bob
Discussion: https://github.com/org/repo/pull/123

Toutes les décisions ne méritent pas un ADR. Voici comment identifier celles qui le nécessitent.

Si vous pouvez répondre « oui » à au moins 3 de ces questions, un ADR est justifié :

  1. Coût de changement : cette décision sera-t-elle coûteuse à modifier plus tard ?
  2. Impact équipe : plusieurs personnes seront-elles affectées ?
  3. Durée de vie : cette décision sera-t-elle pertinente dans 2 ans ?
  4. Alternatives : avez-vous évalué plusieurs options ?
  5. Risque de réinterprétation : quelqu'un pourrait-il mal comprendre ce choix ?

Le tableau suivant applique ce test à des décisions courantes. La colonne de droite donne le critère qui a tranché : c'est elle qu'il faut retenir, parce que votre contexte fera basculer certaines lignes dans l'autre sens.

DécisionADR nécessaire ?Raison
Choix du langage principalOuiImpact majeur, durée de vie longue
Choix du framework webOuiCoût de changement élevé
Stratégie de branching GitOuiImpact équipe, réinterprétation possible
Nom d'une variableNonImpact négligeable
Choix entre deux librairies HTTPSelon contexteDépend de la criticité
Architecture microservices vs monolitheAbsolumentDécision fondamentale

Un repère plus rapide encore, applicable en réunion sans dérouler les cinq questions : si un choix technique déclenche une discussion de plus de trente minutes, il mérite un ADR. La durée de la discussion mesure assez fidèlement le nombre d'options en jeu et le désaccord sur les critères, donc exactement ce qu'un futur lecteur voudra retrouver.

Ces cinq dérives ont un point commun : elles transforment un outil de décision en exercice documentaire. Le symptôme partagé est que plus personne ne lit les ADR, et donc plus personne n'en écrit.

Symptôme : ADR de plus de 3 pages.

Problème : personne ne le lira. L'ADR perd sa fonction de référence rapide.

Solution : un ADR = une décision. Si vous avez besoin de plus d'espace, c'est que vous documentez plusieurs décisions.

Symptôme : « Nous avons choisi X » sans mentionner Y et Z.

Problème : le lecteur ne comprend pas pourquoi X plutôt qu'autre chose.

Solution : toujours documenter au moins 2-3 options évaluées, même si le choix semblait évident.

## Options considérées
### Option 1 : Ne rien faire
Maintenir l'architecture actuelle.
**Rejeté** : ne résout pas le problème de scalabilité.
### Option 2 : Solution choisie
[...]

Symptôme : ADR rédigé 6 mois après la décision.

Problème : le contexte est oublié, les alternatives ne sont plus claires.

Solution : rédiger l'ADR au moment de la décision, même en version draft.

Symptôme : ADR jamais référencé, non intégré au workflow.

Problème : les développeurs ne savent pas qu'il existe.

Solution : intégrer les ADR au processus de revue de code, les lier dans les README.

Symptôme : ADR incompréhensible pour quelqu'un hors de l'équipe immédiate.

Problème : perd sa valeur de transmission de connaissance.

Solution : un bon ADR doit être compréhensible par un développeur rejoignant l'équipe.

Un ADR se range avec le code qu'il concerne, dans le même dépôt et sous la même revue. C'est cette proximité qui le maintient à jour, là où un espace documentaire séparé se périme en quelques mois.

Les ADR vivent dans docs/adr/ à la racine du dépôt, un fichier Markdown par décision, plus un template.md que l'équipe copie à chaque nouvel ADR.

project/
├── docs/
│ └── adr/
│ ├── 0000-use-adr.md
│ ├── 0001-use-typescript.md
│ ├── 0002-choose-react-framework.md
│ ├── 0003-api-rest-vs-graphql.md
│ └── template.md
├── src/
└── README.md

Le nom de fichier suit le format NNNN-titre-en-kebab-case.md, qui est la convention établie par adr-tools et reprise par la plupart des équipes. Le numéro à quatre chiffres assure deux choses : le tri chronologique naturel par le système de fichiers, et une référence courte et stable (« ADR-0042 ») utilisable dans une revue de code ou un ticket. Le fichier 0000-use-adr.md est par convention l'ADR qui décide d'utiliser des ADR, ce qui donne au dépôt son premier exemple.

adr-tools, de Nat Pryce, est le jeu de scripts shell qui a popularisé la convention de nommage NNNN-titre.md. Il gère la numérotation, crée le fichier depuis un template, et surtout met à jour automatiquement le statut de l'ADR remplacé quand vous en créez un successeur avec -s, ce qui est l'opération la plus souvent oubliée quand elle se fait à la main.

Installation et utilisation
# Installation (macOS)
brew install adr-tools
# Initialiser le dossier ADR
adr init docs/adr
# Créer un nouvel ADR
adr new "Use PostgreSQL for main database"
# Crée docs/adr/0001-use-postgresql-for-main-database.md
# Marquer un ADR comme superseded
adr new -s 1 "Migrate to CockroachDB"
# Crée 0002 et met à jour le statut de 0001
# Générer une table des matières
adr generate toc > docs/adr/README.md
# Générer un graphe des liens
adr generate graph | dot -Tpng > docs/adr/graph.png

Log4brains génère un site web navigable à partir de vos ADR :

Installation et utilisation
# Installation
npm install -g log4brains
# Initialiser dans un projet existant
log4brains init
# Prévisualiser en local
log4brains preview
# Générer le site statique
log4brains build

L'outil génère une interface web avec recherche, filtres par statut, et graphe des dépendances entre ADR.

Une validation automatique en intégration continue est ce qui empêche la pratique de se dégrader silencieusement : sans elle, les sections obligatoires finissent par manquer et la numérotation par se trouer. Le workflow ci-dessous se déclenche uniquement sur les pull requests qui touchent docs/adr/, vérifie la présence des sections ## Status, ## Context et ## Decision, puis contrôle que les numéros de fichiers se suivent sans trou.

Deux détails de durcissement méritent attention car ils s'appliquent à tous vos workflows : permissions: {} au niveau du workflow retire au job tous les droits sur le dépôt, qu'on ré-accorde ensuite au strict nécessaire (ici contents: read), et persist-credentials: false empêche actions/checkout de laisser le jeton d'authentification dans le .git/config du runner, où n'importe quelle étape suivante pourrait le lire.

.github/workflows/adr-check.yml
name: ADR Validation
on:
pull_request:
paths:
- 'docs/adr/**'
permissions: {}
jobs:
validate:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Validate ADR format
run: |
for file in docs/adr/[0-9]*.md; do
# Vérifier la présence des sections obligatoires
grep -q "## Status" "$file" || echo "Missing Status in $file"
grep -q "## Context" "$file" || echo "Missing Context in $file"
grep -q "## Decision" "$file" || echo "Missing Decision in $file"
done
- name: Check sequential numbering
run: |
expected=1
for file in docs/adr/[0-9]*.md; do
num=$(basename "$file" | cut -d'-' -f1 | sed 's/^0*//')
if [ "$num" != "$expected" ]; then
echo "Gap in numbering: expected $expected, got $num"
fi
expected=$((expected + 1))
done

Cet ADR, issu d'un projet réel et anonymisé, documente l'adoption de l'Event Sourcing sur un domaine métier. Il vaut surtout par ce qu'il assume : quatre semaines de formation, deux sprints de migration et une infrastructure supplémentaire à exploiter. Un ADR dont la section Conséquences négatives est vide n'est pas un ADR, c'est un argumentaire commercial. La section Actions requises, absente du template MADR standard, est un ajout courant et utile : elle transforme la décision en tâches suivies.

docs/adr/0015-use-event-sourcing-for-orders.md
# ADR-0015 : Utiliser l'Event Sourcing pour le domaine Commandes
## Statut
Accepted
Date: 2024-02-20
Auteurs: Marie Dupont, Jean Martin
Reviewers: Équipe Architecture
## Contexte et problème
Le système de gestion des commandes actuel utilise un modèle CRUD classique.
Nous rencontrons plusieurs problèmes :
1. **Audit insuffisant** : impossible de retracer l'historique complet d'une commande
2. **Conflits de mise à jour** : les modifications concurrentes créent des incohérences
3. **Analyse métier limitée** : les données historiques sont perdues après mise à jour
4. **Conformité RGPD** : difficulté à prouver l'historique des consentements
Le volume actuel est de 50 000 commandes/jour, projection à 200 000 dans 18 mois.
## Decision Drivers
* Traçabilité complète de chaque modification
* Performance en lecture (dashboards temps réel)
* Capacité de « replay » pour correction d'erreurs
* Conformité audit SOC 2
## Options considérées
### Option 1 : Ajouter une table d'audit
Conserver le modèle CRUD et ajouter une table `order_audit` avec triggers.
**Avantages** :
- Changement minimal du code existant
- Équipe familière avec l'approche
**Inconvénients** :
- Ne résout pas les conflits de concurrence
- Performance des triggers à grande échelle
- Audit partiel (pas toutes les modifications)
### Option 2 : Event Sourcing (choisi)
Stocker chaque modification comme un événement immuable.
Reconstituer l'état courant par projection des événements.
**Avantages** :
- Traçabilité totale par design
- Résout la concurrence (append-only)
- Permet le replay et les projections multiples
- Adapté aux patterns CQRS
**Inconvénients** :
- Courbe d'apprentissage (pattern peu connu de l'équipe)
- Complexité des migrations de schéma d'événements
- Besoin d'un event store (infrastructure nouvelle)
### Option 3 : Temporal tables (SQL Server)
Utiliser les temporal tables natives de SQL Server.
**Avantages** :
- Intégré au SGBD
- Pas de changement d'architecture
**Inconvénients** :
- Vendor lock-in
- Pas de support pour les projections personnalisées
- Limité aux requêtes SQL
## Décision
**Nous adoptons l'Event Sourcing pour le domaine Commandes.**
L'implémentation utilisera :
- EventStoreDB comme event store (open-source, optimisé pour ce pattern)
- Projections vers PostgreSQL pour les lectures
- Format CloudEvents pour la structure des événements
## Conséquences
### Positives
* Audit natif : chaque changement est un événement horodaté
* Résolution de la concurrence par versioning des agrégats
* Nouvelles possibilités : replay, what-if analysis, debug temporel
* Base solide pour futures fonctionnalités analytiques
### Négatives
* 4 semaines de formation équipe (workshop Event Sourcing)
* 2 sprints pour migration du domaine Commandes existant
* Nouvelle infrastructure : cluster EventStoreDB à provisionner
* Complexité accrue pour les développeurs juniors
### Actions requises
1. [ ] Formation équipe (S1-S2)
2. [ ] Provisioning EventStoreDB (S2)
3. [ ] Migration progressive domaine Commandes (S3-S6)
4. [ ] Documentation des patterns pour autres domaines
## Liens
* RFC: /docs/rfc/0008-event-sourcing-strategy.md
* Benchmark: /docs/benchmarks/eventstore-performance.md
* Formation: https://internal-wiki/event-sourcing-workshop

Le passage au statut Accepted est irréversible : l'ADR devient immuable, et toute correction ultérieure imposera d'en créer un autre. Cette relecture de quelques minutes est donc le dernier moment où le document se corrige. Les huit points ci-dessous couvrent les défauts constatés le plus souvent en revue.

  • Titre : actionnable et clair (« Use X for Y »)
  • Contexte : le problème est compréhensible sans contexte externe
  • Alternatives : au moins 2 options documentées
  • Décision : clairement identifiable en 30 secondes
  • Conséquences : positives ET négatives listées
  • Longueur : moins de 2 pages imprimées
  • Public : compréhensible par un nouveau membre de l'équipe
  • Liens : références vers documents connexes si nécessaire

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn