Tous les articles
Engineering13 septembre 2026

Concevoir des systèmes qui échouent proprement

Les échecs sont inévitables. Le vrai défi est de concevoir un logiciel qui récupère de manière prévisible au lieu de s'effondrer de façon inattendue.

Une idée est devenue de plus en plus claire en construisant Oblivion : peu importe la quantité d'effort investie dans le développement, les échecs sont inévitables.

Les serveurs redémarrent. Les réseaux deviennent instables. Les APIs externes deviennent indisponibles. Des entrées inattendues apparaissent.

Tôt ou tard, quelque chose se passe mal.

Au début du projet, je voyais ces situations comme des événements exceptionnels. Aujourd'hui, je les considère comme une partie normale de l'environnement opérationnel.

Ce changement de perspective a influencé presque toutes les décisions d'ingénierie qui ont suivi.

L'échec n'est pas l'ennemi

Les ingénieurs logiciel cherchent souvent la perfection.

Les applications ne devraient jamais crasher. Les requêtes ne devraient jamais échouer. Chaque service devrait toujours être disponible.

Même si ces objectifs sont admirables, ils reflètent rarement la réalité.

Les environnements de production sont imprévisibles par nature parce qu'ils dépendent de systèmes que l'on ne contrôle pas.

Internet. Les cloud providers. Les systèmes d'exploitation. Les APIs tierces. L'infrastructure des exchanges.

N'importe lequel peut introduire un comportement inattendu.

Concevoir un logiciel comme si les échecs n'arrivaient jamais crée généralement des systèmes plus fragiles.

Supposer que les choses vont mal tourner

Une habitude que j'ai progressivement adoptée consiste à poser la même question pendant le développement : "Que se passe-t-il si cela échoue ?"

Pas parce que je m'attends à ce que chaque composant échoue immédiatement.

Mais parce qu'à un moment, l'un d'eux échouera.

Si une API ne répond pas, l'application doit-elle s'arrêter entièrement ? Si les données de marché sont temporairement indisponibles, les processus existants doivent-ils continuer ? Si une tâche background crash, tout le reste doit-il s'arrêter aussi ?

Penser à l'échec avant qu'il arrive mène souvent à des designs beaucoup plus simples.

Cela force à séparer les opérations critiques des opérations non critiques et à définir comment le système doit se comporter dans des conditions imparfaites.

La prévisibilité compte

Une leçon m'a surpris plus que les autres. Les utilisateurs tolèrent généralement des échecs occasionnels.

Ce qu'ils n'aiment pas, c'est le comportement imprévisible.

Une application qui signale clairement un problème et récupère proprement crée de la confiance. Une application qui se comporte silencieusement différemment à chaque fois crée de l'incertitude.

La cohérence compte même quand quelque chose se passe mal.

Dans beaucoup de situations, un échec prévisible vaut mieux qu'un succès imprévisible.

La récupération fait partie du design

Les premières versions d'un projet se concentrent souvent entièrement sur le happy path.

Tout fonctionne. Chaque requête réussit. Chaque dépendance est disponible.

Les vrais systèmes passent un temps surprenant en dehors de ce scénario idéal.

La récupération devient donc une partie de l'architecture elle-même.

À quelle vitesse la plateforme doit-elle réessayer ? Comment doit-elle détecter qu'une dépendance est revenue ? Les utilisateurs doivent-ils même remarquer que quelque chose s'est passé ?

Les meilleurs mécanismes de récupération sont souvent ceux dont les utilisateurs ne réalisent jamais l'existence.

La simplicité aide sous pression

Les systèmes complexes deviennent encore plus complexes pendant les incidents.

Quand quelque chose d'inattendu arrive, chaque dépendance supplémentaire, chaque option de configuration et chaque interaction cachée rend le dépannage plus difficile.

Cette prise de conscience a renforcé une idée qui revient souvent dans Oblivion.

Les systèmes simples sont plus faciles à comprendre. Ils sont plus faciles à observer. Ils sont plus faciles à récupérer.

L'élégance ne consiste pas seulement à écrire du code plus propre. Elle consiste à réduire le nombre de choses qui peuvent échouer ensemble.

Avec le recul

Aujourd'hui, je ne mesure plus la qualité d'un logiciel en demandant si des échecs arrivent.

Je pose d'autres questions. La plateforme les détecte-t-elle rapidement ? Récupère-t-elle proprement ? Continue-t-elle à se comporter de manière prévisible ?

Ces questions comptent beaucoup plus en production que la perfection théorique.

Parce qu'un logiciel fiable n'est pas un logiciel qui ne rencontre jamais de problèmes. C'est un logiciel qui sait les gérer quand ils finissent inévitablement par arriver.

Concevoir des systèmes qui échouent proprement