Comprendre le théorème CAP d’Eric Brewer comme modèle pratique : comment cohérence, disponibilité et partitions guident les choix dans les systèmes distribués.

Quand vous stockez les mêmes données sur plus d’une machine, vous gagnez en vitesse et en tolérance aux pannes — mais vous héritez aussi d’un nouveau problème : le désaccord. Deux serveurs peuvent recevoir des mises à jour différentes, des messages peuvent arriver en retard ou pas du tout, et les utilisateurs peuvent lire des réponses différentes selon la réplique qu’ils touchent. CAP est devenu populaire parce qu’il donne aux ingénieurs une manière claire de parler de cette réalité embrouillée sans faire de faux-semblants.
Eric Brewer, informaticien et cofondateur d’Inktomi, a introduit l’idée centrale en 2000 comme une affirmation pratique sur les systèmes répliqués en cas de défaillance. Elle s’est rapidement diffusée parce qu’elle correspondait à ce que les équipes rencontraient déjà en production : les systèmes distribués ne se contentent pas de tomber ; ils se « scindent ».
CAP est le plus utile quand les choses tournent mal — surtout quand le réseau ne se comporte pas. Lors d’une journée saine, de nombreux systèmes peuvent paraître à la fois suffisamment cohérents et disponibles. Le test de résistance arrive quand les machines ne peuvent plus communiquer de façon fiable et que vous devez décider quoi faire des lectures et écritures pendant que le système est divisé.
C’est ce cadrage qui fait de CAP un modèle mental incontournable : il ne prêche pas des bonnes pratiques ; il pose une question concrète — qu’est‑ce que nous sacrifierons durant une partition ?
À la fin de cet article, vous devriez être capable de :
CAP perdure parce qu’il transforme le vague « distributed is hard » en une décision que vous pouvez prendre — et défendre.
Un système distribué est, en termes simples, beaucoup d’ordinateurs essayant d’agir comme un seul. Vous pouvez avoir plusieurs serveurs dans différents racks, régions ou zones cloud, mais pour l’utilisateur c’est « l’app » ou « la base de données ».
Pour que ce système partagé fonctionne à l’échelle réelle, on réplique généralement : on conserve plusieurs copies des mêmes données sur différentes machines.
La réplication est prisée pour trois raisons pratiques :
Jusque‑là, la réplication ressemble à un gain net. Le hic, c’est que la réplication crée un nouveau travail : maintenir toutes les copies en accord.
Si chaque réplique pouvait toujours parler instantanément à toutes les autres, elles pourraient coordonner les mises à jour et rester alignées. Mais les réseaux réels ne sont pas parfaits. Les messages peuvent être retardés, perdus ou routés contournant des défaillances.
Quand la communication est saine, les répliques peuvent généralement échanger des mises à jour et converger vers le même état. Mais quand la communication casse (même temporairement), vous pouvez vous retrouver avec deux versions valides de la « vérité ».
Par exemple, un utilisateur change son adresse de livraison. La réplique A reçoit la mise à jour, la réplique B non. Maintenant le système doit répondre à une question apparemment simple : quelle est l’adresse actuelle ?
C’est la différence entre :
La pensée CAP commence précisément ici : une fois la réplication en place, le désaccord sous défaillance de communication n’est pas un cas marginal — c’est le problème de conception central.
CAP est un modèle mental pour ce que les utilisateurs ressentent réellement quand un système est réparti sur plusieurs machines (souvent en plusieurs emplacements). Il ne décrit pas des systèmes « bons » ou « mauvais » — juste la tension que vous devez gérer.
La cohérence concerne l’accord. Si vous mettez quelque chose à jour, la prochaine lecture (de n’importe où) reflétera‑t‑elle cette mise à jour ?
Du point de vue utilisateur, c’est la différence entre « je viens de le changer, et tout le monde voit la nouvelle valeur » et « certaines personnes voient encore l’ancienne valeur pendant un moment ».
La disponibilité signifie que le système répond aux requêtes — lectures et écritures — par un résultat de succès. Pas « le plus rapide possible », mais « il ne refuse pas de vous servir ».
En cas de problème (un serveur en panne, un pépin réseau), un système disponible continue d’accepter les requêtes, même s’il doit répondre avec des données légèrement périmées.
Une partition est quand le réseau se scinde : des machines tournent, mais les messages entre certaines d’entre elles ne passent plus (ou arrivent trop tard pour être utiles). Dans les systèmes distribués, vous ne pouvez pas traiter cela comme impossible — il faut définir le comportement quand ça arrive.
Imaginez deux boutiques qui vendent le même produit et partagent un « stock unique ». Un client achète le dernier article dans la boutique A, donc A écrit stock = 0. Au même moment, une partition réseau empêche B d’en être informée.
Si B reste disponible, elle peut vendre un article qu’elle n’a plus (accepter la vente pendant la partition). Si B fait primer la cohérence, elle peut refuser la vente tant qu’elle ne confirme pas le stock le plus récent (refuser le service pendant la coupure).
Une « partition » n’est pas seulement « Internet est en panne ». C’est toute situation où des parties de votre système ne peuvent pas se parler de façon fiable — même si chaque partie semble tourner correctement.
Dans un système répliqué, les nœuds échangent constamment des messages : écritures, acquittements, heartbeats, élections de leader, requêtes de lecture. Une partition survient quand ces messages cessent d’arriver (ou arrivent trop tard), créant un désaccord sur la réalité : « L’écriture a‑t‑elle eu lieu ? », « Qui est le leader ? », « Le nœud B est‑il vivant ? »
La communication peut échouer de manière fragmentaire :
Le point important : les partitions sont souvent une dégradation, pas une coupure nette on/off. Du point de vue de l’application, « assez lent » peut être indiscernable de « down ».
En ajoutant des machines, des réseaux, des régions et des pièces mobiles, il y a simplement plus d’opportunités pour que la communication casse temporairement. Même si les composants individuels sont fiables, le système global connaît des défaillances parce qu’il a plus de dépendances et plus de coordination inter‑nœuds.
Vous n’avez pas besoin d’assumer un taux d’échec précis pour accepter la réalité : si votre système tourne assez longtemps et couvre assez d’infrastructure, les partitions arriveront.
Tolérer les partitions signifie que votre système est conçu pour continuer à fonctionner pendant une scission — même quand les nœuds ne peuvent pas s’accorder ou confirmer ce que l’autre côté a vu. Cela force un choix : continuer à servir (au risque d’incohérences) ou arrêter/refuser certaines requêtes (préserver la cohérence).
Une fois la réplication en place, une partition est simplement une rupture de communication : deux parties de votre système ne peuvent pas parler de façon fiable pendant un moment. Les répliques tournent toujours, les utilisateurs continuent de cliquer, et votre service reçoit encore des requêtes — mais les répliques ne peuvent pas s’accorder sur la vérité la plus récente.
C’est la tension CAP en une phrase : pendant une partition, vous devez choisir de prioriser la Cohérence (C) ou la Disponibilité (A). Vous n’obtenez pas les deux en même temps.
Vous dites : « je préfère être correct plutôt que réactif. » Quand le système ne peut pas confirmer qu’une requête maintiendra toutes les répliques synchrones, il doit échouer ou attendre.
Effet pratique : certains utilisateurs voient des erreurs, des timeouts ou des messages « réessayez » — surtout pour les opérations qui modifient des données. C’est courant quand vous préférez refuser un paiement plutôt que de risquer un double débit, ou bloquer une réservation de siège plutôt que de surgérer.
Vous dites : « je préfère répondre plutôt que bloquer. » Chaque côté de la partition continue d’accepter des requêtes, même s’il ne peut pas se coordonner.
Effet pratique : les utilisateurs obtiennent des réponses réussies, mais les données lues peuvent être obsolètes, et des mises à jour concurrentes peuvent entrer en conflit. Vous comptez ensuite sur une réconciliation ultérieure (règles de fusion, last‑write‑wins, revue manuelle, etc.).
Ce n’est pas toujours un réglage global. Beaucoup de produits mélangent les stratégies :
Le moment clé est de décider — pour chaque opération — ce qui est pire : bloquer un utilisateur maintenant, ou résoudre une vérité conflictuelle plus tard.
Le slogan « choisissez deux » est mémorable, mais il induit souvent en erreur en faisant croire que CAP est un menu de trois fonctionnalités dont on ne peut en garder que deux pour toujours. CAP concerne ce qui arrive quand le réseau cesse de coopérer : pendant une partition (ou tout ce qui y ressemble), un système distribué doit choisir entre retourner des réponses cohérentes et rester disponible pour chaque requête.
Dans les systèmes réels, les partitions ne sont pas un réglage désactivable. Si votre système couvre des machines, racks, zones ou régions, alors des messages peuvent être retardés, perdus, réordonnés ou routés de manière étrange. C’est une partition du point de vue du logiciel : les nœuds ne peuvent pas s’accorder suffisamment bien.
Même si le réseau physique est correct, des défaillances ailleurs créent le même effet : nœuds surchargés, pauses GC, voisins bruyants, problèmes DNS, load balancers instables. Le résultat est le même : certaines parties du système ne peuvent pas se coordonner.
Les applications n’expérimentent pas la « partition » comme un événement binaire net. Elles subissent des pics de latence et des timeouts. Si une requête timeoute après 200 ms, peu importe si le paquet est arrivé à 201 ms ou jamais : l’app doit décider quoi faire ensuite. Du point de vue de l’app, une communication lente est souvent indiscernable d’une communication cassée.
Beaucoup de systèmes réels sont pour la plupart cohérents ou pour la plupart disponibles, selon la configuration et les conditions d’exploitation. Les timeouts, politiques de retry, tailles de quorum et options « read your writes » peuvent faire évoluer le comportement.
En conditions normales, une base de données peut sembler fortement cohérente ; sous stress ou lors d’un pépin inter‑régions, elle peut commencer à rejeter des requêtes (favorisant la cohérence) ou renvoyer des données plus anciennes (favorisant la disponibilité).
CAP vise moins à étiqueter des produits qu’à comprendre le compromis que vous faites quand le désaccord arrive — surtout quand ce désaccord est causé par une simple lenteur.
Les discussions CAP font parfois paraître la cohérence binaire : « parfaite » ou « tout est permis ». Les systèmes réels offrent un menu de garanties, chacune donnant une expérience utilisateur différente quand les répliques divergent ou qu’un lien réseau casse.
La cohérence forte (souvent dite « linéarisable ») signifie qu’une fois qu’une écriture est acquittée, toute lecture ultérieure — quel que soit la réplique — renverra cette écriture.
Son coût : pendant une partition ou lorsque la minorité des répliques est inaccessible, le système peut retarder ou rejeter lectures/écritures pour éviter d’afficher des états conflictuels. Les utilisateurs le remarquent via des timeouts, des messages « réessayez » ou un comportement temporaire en lecture seule.
La cohérence éventuelle promet que si aucune nouvelle mise à jour n’a lieu, toutes les répliques convergeront. Elle ne promet pas que deux utilisateurs lisant maintenant verront la même chose.
Ce que l’utilisateur peut remarquer : une photo de profil récemment mise à jour qui « revient en arrière », des compteurs qui accusent du retard, ou un message envoyé qui n’apparaît pas sur un autre appareil pendant un court instant.
Vous pouvez souvent obtenir une meilleure expérience sans exiger la cohérence forte :
Ces garanties correspondent bien à la manière dont les gens pensent (« ne me montre pas mes propres modifications disparaître ») et sont souvent plus faciles à maintenir en cas de pannes partielles.
Commencez par les promesses produit, pas par le jargon :
La cohérence est un choix produit : définissez ce qu’« être faux » signifie pour un utilisateur, puis choisissez la garantie la plus faible qui empêche ce cas inacceptable.
La disponibilité dans CAP n’est pas un argument marketing (« cinq 9 ») — c’est une promesse que vous faites aux utilisateurs sur ce qui arrive quand le système ne peut pas être certain.
Quand les répliques ne peuvent pas s’accorder, vous choisissez souvent entre :
Les utilisateurs ressentent cela comme « l’app fonctionne » versus « l’app est correcte ». Ni l’un ni l’autre n’est universellement meilleur ; le bon choix dépend de ce que « faux » signifie dans votre produit. Un fil social légèrement périmé est agaçant. Un solde de compte périmé peut être dangereux.
Deux comportements courants en période d’incertitude :
Ce n’est pas un choix purement technique ; c’est une politique. Le produit doit définir ce qu’il est acceptable d’afficher et ce qui ne doit jamais être deviné.
La disponibilité est rarement tout ou rien. Pendant une scission, vous pouvez observer une disponibilité partielle : certaines régions, réseaux ou groupes d’utilisateurs réussissent tandis que d’autres échouent. Cela peut être un choix délibéré (continuer à servir là où la réplique locale est saine) ou accidentel (déséquilibres de routage, quorum inatteignable).
Un compromis pratique est le mode dégradé : continuer à servir les actions sûres tout en restreignant celles à risque. Par exemple, autoriser la navigation et la recherche, mais désactiver temporairement « transférer des fonds », « changer le mot de passe » ou d’autres opérations où la correction et l’unicité comptent.
CAP paraît abstrait jusqu’à ce que vous le mettiez en correspondance avec ce que vos utilisateurs vivent pendant une scission réseau : préférez‑vous que le système continue de répondre, ou qu’il s’arrête pour éviter de retourner/acceptor des données conflictuelles ?
Imaginez deux datacenters acceptant des commandes alors qu’ils ne peuvent pas communiquer.
Si vous maintenez le checkout disponible, chaque côté peut vendre le « dernier article » et vous surventerez. Cela peut être acceptable pour des biens à faible enjeu (vous gérez en backorder ou excusez), mais pénalisant pour des drops en quantité limitée.
Si vous choisissez la cohérence, vous pouvez bloquer les nouvelles commandes quand vous ne pouvez pas confirmer le stock global. Les utilisateurs voient « réessayez plus tard », mais vous évitez de vendre ce que vous ne pouvez pas honorer.
L’argent est le domaine classique où se tromper coûte cher. Si deux répliques acceptent des retraits indépendamment pendant une scission, un compte peut devenir négatif.
Les systèmes préfèrent souvent la cohérence pour les écritures critiques : refuser ou retarder les actions si l’on ne peut pas confirmer le solde actuel. Vous échangez un peu de disponibilité (échecs de paiement temporaires) contre correction, traçabilité et confiance.
Dans le chat et les fils sociaux, les utilisateurs tolèrent généralement de petites incohérences : un message arrive quelques secondes plus tard, un compteur de likes est décalé, une métrique s’actualise plus tard.
Ici, concevoir pour la disponibilité peut être un bon choix produit, tant que vous précisez quels éléments sont « finalement cohérents » et que vous savez fusionner proprement les mises à jour.
Le « bon » choix CAP dépend du coût d’être faux : remboursements, exposition légale, perte de confiance, chaos opérationnel. Décidez où vous pouvez tolérer la staleness temporaire — et où vous devez échouer fermé.
Une fois que vous avez décidé quoi faire durant une rupture réseau, il faut des mécanismes qui concrétisent cette décision. Ces patterns apparaissent dans les bases de données, systèmes de messages et API — même si le produit ne parle jamais explicitement de « CAP ».
Un quorum, c’est simplement « la majorité des répliques sont d’accord ». Si vous avez 5 copies d’une donnée, la majorité est 3.
En exigeant que lectures et/ou écritures contactent une majorité, vous réduisez la probabilité de renvoyer des données périmées ou conflictuelles. Par exemple, si une écriture doit être acquittée par 3 répliques, il est plus difficile que deux groupes isolés acceptent des « vérités » différentes.
L’échange est la latence et la portée : si vous n’atteignez pas la majorité (partition, panne), le système peut refuser l’opération — il choisit la cohérence plutôt que la disponibilité.
Beaucoup de problèmes d’« disponibilité » ne sont pas des pannes nettes mais des réponses lentes. Définir un timeout court rend l’expérience réactive, mais augmente les chances de considérer des succès lents comme des échecs.
Les retries peuvent récupérer d’états transitoires, mais des retries agressifs peuvent surcharger un service déjà fragilisé. Le backoff (attendre un peu plus entre les retries) et le jitter (aléa) empêchent que les retries deviennent un pic de trafic.
L’important est d’aligner ces réglages avec votre promesse : « toujours répondre » implique généralement plus de retries et de repli ; « ne jamais mentir » implique des limites plus strictes et des erreurs explicites.
Si vous choisissez de rester disponible pendant les partitions, des répliques peuvent accepter des mises à jour différentes et vous devez réconcilier ensuite. Approches courantes :
Les retries peuvent créer des doublons : débit d’une carte en double ou soumission d’une commande deux fois. L’idempotence empêche cela.
Un pattern courant est la clé d’idempotence (idempotency key) envoyée avec chaque requête. Le serveur conserve le premier résultat et renvoie le même résultat pour les répétitions — ainsi les retries améliorent la disponibilité sans corrompre les données.
La plupart des équipes « choisissent » une posture CAP sur un tableau blanc — puis découvrent en production que le système se comporte différemment sous stress. Valider signifie créer volontairement les conditions où les compromis CAP deviennent visibles, et vérifier que votre système réagit comme prévu.
Vous n’avez pas besoin d’une coupure réelle pour apprendre : utilisez l’injection de fautes contrôlées en staging (et prudemment en production) pour simuler des partitions :
Le but est de répondre à des questions concrètes : les écritures sont‑elles rejetées ou acceptées ? les lectures retournent‑elles des données périmées ? le système récupère‑t‑il automatiquement et combien de temps prend la réconciliation ?
Si vous voulez valider ces comportements tôt (avant d’investir des semaines à monter des services), il peut aider de prototyper rapidement. Par exemple, des équipes utilisant Koder.ai débutent souvent par générer un petit service (souvent un backend Go avec PostgreSQL plus une UI React) puis itèrent sur les comportements comme retries, clés d’idempotence et flux en « mode dégradé » dans un bac à sable.
Les checks de disponibilité traditionnels ne détecteront pas le comportement « disponible mais faux ». Surveillez :
Les opérateurs ont besoin d’actions prédéfinies quand une partition arrive : quand geler les écritures, quand basculer, quand dégrader des fonctionnalités, et comment valider la sécurité de la réunification.
Préparez aussi le comportement visible pour l’utilisateur. Si vous choisissez la cohérence, le message peut être « Nous ne pouvons pas confirmer votre mise à jour pour l’instant — veuillez réessayer. » Si vous choisissez la disponibilité, soyez explicite : « Votre mise à jour peut mettre quelques minutes à apparaître partout. » Un wording clair réduit la charge du support et préserve la confiance.
Quand vous prenez une décision système, CAP est surtout utile comme un bref audit « qu’est‑ce qui casse pendant une partition ? » — pas comme un débat théorique. Utilisez cette checklist avant de choisir un mode de base de données, une stratégie de cache ou un mode de réplication.
Posez ces questions dans l’ordre :
Si une partition arrive, vous décidez ce que vous protégez en priorité.
Évitez un réglage global comme « nous sommes AP ». Décidez par :
Exemple : durant une partition, vous pouvez bloquer les écritures sur payments (préserver la cohérence) tout en gardant les lectures de product_catalog disponibles via cache.
Écrivez ce que vous tolérez, avec exemples :
Si vous ne pouvez pas décrire l’incohérence en exemples simples, vous aurez du mal à la tester et à expliquer les incidents.
Sujets suivants qui s’accordent bien avec cette checklist : consensus (/blog/consensus-vs-cap), modèles de cohérence (/blog/consistency-models-explained) et SLOs / budgets d’erreur (/blog/sre-slos-error-budgets).
CAP est un modèle mental pour les systèmes répliqués sous défaillance de communication. Il est particulièrement utile quand le réseau est lent, perd des paquets ou se scinde, car c’est alors que les répliques ne peuvent pas s’accorder et que vous êtes forcé de choisir entre :
Il aide à transformer le « distributed is hard » en une décision produit et ingénierie concrète.
Un véritable scénario CAP nécessite les deux :
Si votre système est mono‑nœud ou si vous ne répliquez pas l’état, les compromis CAP ne sont pas le problème central.
Une partition est toute situation où des parties de votre système ne peuvent pas communiquer de manière fiable ou dans les limites de temps requises — même si chaque machine tourne toujours.
Concrètement, une “partition” se manifeste souvent par :
Du point de vue de l’application, « trop lent » peut être la même chose que « en panne ».
Cohérence (C) signifie que les lectures reflètent l’écriture la plus récente reconnue, quel que soit le nœud consulté. Les utilisateurs le vivent comme « j’ai modifié, et tout le monde voit la même chose ».
Disponibilité (A) signifie que chaque requête reçoit une réponse réussie (pas forcément la donnée la plus récente). Les utilisateurs le vivent comme « l’app continue de fonctionner », éventuellement avec des résultats périmés.
Pendant une partition, on ne peut en général pas garantir les deux à la fois pour toutes les opérations.
Parce que les partitions ne sont pas optionnelles dans les systèmes répartis qui couvrent plusieurs machines, racks, zones ou régions. Si vous répliquez, vous devez définir un comportement quand les nœuds ne peuvent pas se coordonner.
« Tolérer les partitions » signifie généralement : lorsque la communication se rompt, le système a une façon définie d’opérer — soit en rejetant/pausant certaines actions (préserver la cohérence), soit en servant des résultats au mieux (préserver la disponibilité).
Si vous privilégiez la cohérence, vous :
Cela est courant pour les mouvements d’argent, la réservation d’inventaire et les changements d’autorisations — là où se tromper est pire que d’être temporairement indisponible.
Si vous privilégiez la disponibilité, vous :
Les utilisateurs voient moins d’erreurs dures, mais peuvent constater des données obsolètes, des effets dupliqués sans idempotence, ou des mises à jour conflictuelles à corriger.
Oui. Vous pouvez choisir différemment selon l’endpoint ou le type de données. Stratégies courantes :
Évitez un réglage global « nous sommes AP/CP » qui ne correspond rarement aux besoins produits réels.
Options utiles :
Validez en créant les conditions où la divergence devient visible :
Choisissez la garantie la plus faible qui empêche le « mauvais » visible par l’utilisateur que vous ne pouvez pas tolérer.
Préparez aussi des runbooks et des messages utilisateurs cohérents avec le comportement choisi (fail closed vs fail open).