L’ère du « regret des microservices » : pourquoi les équipes reviennent discrètement au monolithe
Pourquoi startups et équipes tech reviennent au monolithe modulaire après avoir découvert le coût caché et la complexité de microservices adoptés trop tôt.
Pendant un temps, les microservices semblaient être l’étape logique pour tout produit logiciel un peu sérieux.
Dès qu’une startup commençait à grandir, la discussion sur l’architecture finissait par dériver vers le découpage de l’application en services plus petits. L’authentification devenait un service à part. Les paiements étaient séparés. Les notifications partaient ailleurs. Très vite, un produit qui avait démarré comme une application relativement simple pouvait se retrouver avec un nombre étonnamment élevé de services derrière lui.
Et honnêtement, il y avait de bonnes raisons de le faire.
Les microservices résolvent de vrais problèmes. Ils permettent aux équipes de déployer des parties d’un système indépendamment, de faire monter en charge certaines tâches sans tout faire monter en charge, et de donner aux grandes équipes d’ingénierie davantage de responsabilité sur différentes parties d’un produit.
Pour les entreprises qui opèrent à grande échelle, cette séparation peut être extrêmement utile.
Le problème commence quand l’architecture arrive avant le problème.
Une startup de cinq personnes avec quelques milliers d’utilisateurs n’a pas les mêmes besoins d’architecture qu’une entreprise avec des centaines d’ingénieurs et des millions de requêtes par jour. Et pourtant, il est étonnamment facile de construire le petit produit comme si ce futur était déjà là.
C’est là que commence le regret des microservices.
Le problème, ce ne sont pas les microservices
Mettons une chose au clair : ce n’est pas un plaidoyer contre les microservices.
Ils ne sont pas mauvais. Dans la bonne situation, ils sont extrêmement utiles.
Le problème, c’est de les adopter simplement parce qu’ils semblent être la « bonne » façon de construire une application moderne, plutôt que parce que le produit en a réellement besoin.
Imaginez une petite application avec de l’authentification, des paiements, des profils utilisateur et des notifications.
Vous pourriez transformer chacun de ces éléments en service à part. Sur un schéma d’architecture, ça peut avoir l’air propre et bien organisé.
Mais maintenant, chaque service a besoin d’un processus de déploiement, de monitoring, de logs, de configuration, d’authentification, de gestion des erreurs et de documentation.
Ce qui aurait pu être un simple appel de fonction dans la même application devient une requête réseau.
Et les requêtes réseau peuvent échouer.
Un service peut dépasser son délai. Une base de données peut devenir temporairement indisponible. Une requête peut être relancée. Un service peut déployer un changement avant qu’un autre soit prêt à le recevoir. D’un coup, vous voilà face à des problèmes de systèmes distribués qui n’existaient tout simplement pas quand tout vivait dans une seule application.
Le produit n’est pas forcément devenu plus compliqué.
L’architecture, si.
Le coût caché d’être « scalable »
Quand on parle de scalabilité, on pense généralement au trafic.
Le système peut-il encaisser dix fois plus d’utilisateurs ? Traiter plus de requêtes ? Une partie précise de l’application peut-elle monter en charge indépendamment ?
Ce sont des questions importantes, mais il existe une autre forme de scalabilité qu’on oublie facilement : la capacité de l’équipe elle-même à comprendre et à faire évoluer le système.
Un système capable d’encaisser des millions de requêtes mais qu’il faut trois jours pour comprendre avant de faire un petit changement n’est pas vraiment agréable à faire évoluer.
C’est l’une des raisons pour lesquelles le monolithe modulaire redevient séduisant.
Au lieu de tout découper immédiatement en services indépendants, une équipe peut garder une seule application tout en maintenant des frontières claires à l’intérieur. L’authentification, la facturation, les utilisateurs, les notifications et les autres domaines peuvent avoir leurs propres modules et responsabilités sans exiger un service et une infrastructure à part pour chacun.
Vous avez de la structure sans payer tout de suite le coût opérationnel complet des systèmes distribués.
Et si l’un de ces modules finit par devenir assez gros pour justifier un service à part, vous pourrez l’extraire plus tard.
Cette souplesse compte.
Des captures d’écran prêtes pour les stores en quelques minutes — gratuit, sans filigrane à l’export.
Launch Shots est gratuit pour commencer. Tous les modèles (plus de 110), plus de 220 cadres d’appareil et des mockups 3D, la traduction IA et l’envoi direct vers App Store Connect et la Google Play Console. Sans carte bancaire.
Commencer gratuitement →Vous n’avez pas à prédire l’avenir
L’une des façons les plus simples de sur-concevoir une startup, c’est de bâtir autour de problèmes qui ne se sont pas encore posés.
« On aura peut-être des millions d’utilisateurs. »
« On aura peut-être plusieurs équipes d’ingénierie. »
« On aura peut-être besoin de faire monter ce composant en charge indépendamment. »
« On changera peut-être de base de données plus tard. »
Tout cela est possible.
Mais possible ne veut pas dire probable, et probable ne veut pas dire que vous devez le résoudre aujourd’hui.
L’architecture d’une startup devrait surtout répondre aux problèmes que l’équipe rencontre réellement, plutôt qu’à une version imaginaire de l’entreprise dans cinq ans.
Si le système doit un jour être découpé, vous pourrez le découper quand la raison deviendra claire.
D’ici là, garder les choses ensemble peut accélérer le développement, faciliter le débogage et rendre l’ensemble du système plus facile à comprendre.
Ça ne veut pas dire ignorer la croissance future.
Ça veut dire accepter que vous ne savez probablement pas encore exactement à quoi elle ressemblera.
Et ce n’est pas grave.
Chaque service crée une responsabilité de plus
Il est facile de regarder une architecture en microservices et d’y voir un ensemble de petites pièces joliment séparées.
Ce qu’on oublie, c’est que chacune de ces pièces a un coût opérationnel.
Un service doit être déployé. Il lui faut du monitoring. Des logs. Des alertes. De la configuration. Quelqu’un doit savoir ce qui se passe quand il tombe. Quelqu’un doit enquêter quand sa latence grimpe d’un coup.
Maintenant, imaginez ça pour dix services.
Puis vingt.
Puis cinquante.
Pour une grande organisation, ce surcoût peut tout à fait en valoir la peine. L’indépendance entre équipes et systèmes peut apporter assez de valeur pour justifier toute cette complexité.
Pour une petite équipe, en revanche, ça peut devenir une distraction.
Au lieu de passer du temps à améliorer le produit, les développeurs peuvent finir par consacrer une part importante de leur temps à entretenir toute la machinerie nécessaire pour faire tourner l’architecture.
Et c’est l’un des coûts les moins visibles des microservices.
Le code lui-même n’est pas forcément difficile.
C’est tout ce qu’il y a autour du code qui finit par s’accumuler.
Le monolithe modulaire mérite plus de respect
Le monolithe modulaire se situe quelque part entre les deux extrêmes.
C’est toujours une seule application, mais ce n’est pas forcément une base de code géante et emmêlée où tout peut accéder à tout.
L’application peut être divisée en modules logiques, avec des responsabilités et des frontières claires.
Les développeurs peuvent donc raisonner en domaines séparés sans introduire une frontière réseau entre chaque domaine.
Le développement peut aussi rester relativement simple. Lancer l’application en local est plus facile. Le débogage est généralement plus direct. Les transactions peuvent être plus simples à gérer. Le déploiement n’exige pas de coordonner une collection de services indépendants.
Et il y a moins d’infrastructure à entretenir.
Surtout, commencer avec un monolithe ne veut pas dire que vous y êtes coincé pour toujours.
Un monolithe bien structuré peut même faciliter un futur passage aux microservices, parce que les frontières existent déjà.
Si le module de facturation finit par être la partie du système qui a vraiment besoin d’une montée en charge ou d’un déploiement indépendants, vous pouvez l’extraire.
Vous n’avez pas à tout extraire simplement parce qu’une partie doit changer.
C’est ça, le vrai avantage de bien concevoir ses frontières.
Vous vous laissez des options.
Alors, quand les microservices ont-ils vraiment du sens ?
Il n’existe pas de nombre magique d’utilisateurs à partir duquel une entreprise devrait soudain passer d’un monolithe aux microservices.
Le trafic seul ne suffit pas à prendre cette décision.
Les microservices deviennent bien plus intéressants quand différentes parties du système ont des besoins de montée en charge vraiment différents, quand les équipes ont besoin de déployer indépendamment, quand les frontières entre domaines sont bien comprises, ou quand certains composants exigent des technologies ou une infrastructure complètement différentes.
La structure de l’équipe compte aussi.
Une organisation avec des dizaines d’équipes d’ingénierie a des problèmes de coordination très différents de ceux d’une startup de quatre développeurs.
L’architecture doit répondre à ces réalités.
Si vous séparez un service parce qu’un composant pose un vrai problème de montée en charge, c’est une raison.
Si vous isolez un domaine parce que plusieurs équipes doivent y travailler indépendamment, c’est une raison.
Si vous le faites parce qu’« on en aura peut-être besoin un jour », il vaut peut-être mieux attendre.
La meilleure décision d’architecture est souvent celle qui résout le problème d’aujourd’hui sans en créer cinq nouveaux.
L’architecture la plus sophistiquée est peut-être la plus ennuyeuse
Le génie logiciel a tendance à récompenser la complexité.
Un schéma rempli de services, de files d’attente, de bases de données, de bus d’événements et de composants d’infrastructure peut impressionner.
Mais les utilisateurs ne voient rien de tout ça.
Ils voient si le produit se charge vite. Ils voient si leurs données sont en sécurité. Ils voient si une fonctionnalité marche quand ils en ont besoin. Ils voient si le produit leur paraît fiable.
C’est, au fond, ce que l’architecture est censée servir.
Parfois, ça veut dire des microservices.
Parfois, un monolithe modulaire.
Parfois, quelque chose entre les deux.
L’erreur, c’est de croire qu’une architecture plus compliquée est automatiquement le signe d’une équipe d’ingénierie plus mature.
Une bonne architecture, ce n’est pas le nombre de technologies que vous arrivez à caser dans un système.
C’est construire quelque chose d’assez simple à comprendre, d’assez fiable à exploiter et d’assez souple pour évoluer quand le produit évolue.
C’est peut-être pour ça que certaines équipes reviennent au monolithe.
Elles n’abandonnent pas forcément la scalabilité.
Elles se rendent compte que la simplicité est aussi une forme de scalabilité, surtout quand ce qui doit passer à l’échelle n’est pas seulement l’infrastructure, mais l’équipe qui construit le produit.
