- Séparer trop tôt le code en microservices dans une startup en phase initiale entraîne une baisse importante de la productivité de l’équipe et une hausse de la complexité
- Une architecture monolithique optimise les chances de survie grâce à des déploiements simples, une mise en production rapide des nouvelles fonctionnalités et une collaboration efficace
- Les microservices n’apportent les bénéfices du découpage que lorsqu’il existe un besoin de forte montée en charge, des charges de travail variées ou des exigences d’exécution distinctes
- Une séparation excessive des services, la prolifération des dépôts, un environnement de développement local instable et des divergences dans la stack technique conduisent à un ralentissement et à une baisse du moral des équipes
- Pour une startup, le meilleur choix est de commencer par un monolithe et de ne découper que lorsqu’un goulot d’étranglement clair apparaît
Introduction et contexte
- La survie d’une startup dépend de sa capacité à itérer vite, à livrer de nouvelles fonctionnalités et à créer de la valeur pour les utilisateurs
- L’architecture de base du projet, la stack technique et le choix du langage de programmation ont un impact direct sur la vitesse de l’équipe
- L’adoption précoce des microservices peut paraître élégante sur le papier, mais en pratique elle provoque une baisse de productivité, des services inachevés et un excès de complexité
- Données : orchestration des services, problèmes liés à Docker et aux scripts, CI/CD dupliquée, couplage entre services, coût de l’observabilité, dispersion des tests, etc. — autant de coûts de développement supplémentaires
- Au lieu de foncer vers une architecture complexe, le texte insiste sur l’importance d’une architecture pragmatique
Les points forts du monolithe
- Qu’il s’agisse d’un SaaS ou d’un simple wrapper de base de données, une application se complexifie avec le temps, mais une architecture monolithique reste plus simple et plus facile à garder flexible
- Le déploiement est facile, l’écosystème est bien soutenu par des frameworks populaires comme Django, ASP.Net ou Nest.js, et les bénéfices de la communauté open source sont importants
- Cas concret : dans une startup de l’immobilier, un monolithe Laravel a permis de gérer facilement de nombreuses intégrations tierces et l’extension des fonctionnalités
- Il a été possible de se concentrer sur les besoins métier et les attentes sans introduire une infrastructure complexe ni découper en microservices
- Leçon : la simplicité de l’architecture aide l’équipe à se concentrer sur les déploiements, et l’échelle reste suffisante tant qu’on évite d’échouer dans la modularisation interne
Les microservices sont-ils toujours le meilleur choix ?
- Beaucoup d’ingénieurs pensent que les microservices sont la bonne réponse par défaut, alors qu’en réalité ils ne révèlent leur valeur que lorsqu’il existe une raison particulière, comme des besoins de montée en charge
- Avec une petite équipe, à petite échelle et dans une phase de changements rapides, ils produisent au contraire des effets négatifs : infrastructure dupliquée, développement local plus lent, cycles d’itération plus longs
- Même des entreprises comme Segment ont connu une transition imposée par une structure inefficace
- Leçon : les microservices sont un outil pour résoudre des goulots d’étranglement, pas un modèle initial
Pourquoi les microservices échouent surtout en phase de démarrage
1. Des frontières de service arbitraires
- En s’appuyant sur la conception orientée domaine ou la clean architecture, on tente de découper les services par logique métier → mais les frontières de service ne correspondent pas réellement à la logique effective
- Exemple : séparer utilisateurs, authentification et autorisations accroît la complexité des déploiements et la difficulté de développement des API
- Découper avant même qu’un véritable goulot d’étranglement n’apparaisse rend le système plus instable et plus lent
- Simuler un futur découpage via des flags ou des toggles internes, plutôt que lancer précipitamment des travaux d’infrastructure, permet d’explorer des frontières organiques plus efficacement
- Leçon : les décisions de découpage doivent reposer sur les vrais goulots d’étranglement, pas sur la théorie
2. Trop de dépôts et trop d’infrastructure
- Style de code, tests, configuration, documentation, CI/CD : chaque élément se multiplie avec le nombre de services
- Une structure en monorepo permet de gérer toute la configuration au même endroit, d’améliorer la cohérence du code et l’efficacité de la collaboration
- Dans l’écosystème Node.js, des outils comme
nx ou turborepo facilitent la gestion des dépendances et des builds entre services internes
- Parmi les inconvénients : dépendances complexes, besoin d’optimiser les performances de la CI, nécessité d’outils de build plus rapides
- Dans l’écosystème Go aussi, il est possible de commencer avec un workspace unique puis d’envisager un découpage en modules lorsque la taille augmente
- Leçon : une petite équipe peut gagner du temps grâce à un monorepo et une infrastructure partagée
3. Un environnement de développement local instable
- Temps de lancement excessif en local, scripts complexes, dépendances propres à chaque système : tout cela provoque des retards d’onboarding et une baisse de productivité
- Le manque de documentation, les problèmes de compatibilité et les bricolages spécifiques à un OS (par exemple des scripts réservés à macOS) deviennent des obstacles
- Sur un projet, un proxy Node.js a permis d’atténuer la complexité de Docker et de réduire le temps d’onboarding des développeurs
- Leçon : si l’application ne tourne que sur un seul OS, la productivité de l’équipe finit par dépendre de la fiabilité d’un seul laptop
4. Des stacks techniques incohérentes
- Node.js et Python sont adaptés à l’itération rapide, mais dans un environnement de microservices, ils provoquent souvent des problèmes de désalignement entre build et runtime
- Go présente des avantages grâce aux binaires statiques, à la rapidité des builds et à la simplicité d’exploitation
- Il faut choisir sa stack avec soin dès le début et, si nécessaire, combiner plusieurs langages via des protocoles comme gRPC
- Sauf besoins particuliers comme le ML ou l’ETL, mélanger les stacks ne fait généralement qu’ajouter de la complexité
- Leçon : choisissez une stack adaptée à la réalité de l’équipe, pas à une vision idéalisée
5. Complexité cachée : communication et monitoring
- Avec les microservices, des éléments comme la service discovery, le versionnement des API, le distributed tracing et la gestion centralisée des logs deviennent indispensables
- Le suivi d’un bug ou d’un incident, qui peut se résumer à une stack trace dans un monolithe, devient bien plus complexe dans un environnement distribué
- Pour bien faire, il faut introduire des outils spécialisés comme OpenTelemetry et mettre en place une véritable stack d’observabilité
- Il faut reconnaître qu’un système distribué implique un investissement obligatoire dans des défis d’ingénierie supplémentaires
Quand les microservices sont pertinents
- Isolation des workloads : il peut être efficace de séparer certaines tâches asynchrones comme le traitement d’images ou l’OCR
- Besoins de montée en charge asymétriques : si une API web et une charge ML ont des contraintes matérielles ou opérationnelles différentes, il est pertinent de les séparer
- Besoin d’un autre runtime : des composants incompatibles avec le runtime principal de l’application, comme du code C++ legacy, peuvent être maintenus comme services distincts
- Comme le montrent les grandes organisations d’ingénierie (par exemple Uber), cela n’est adapté que lorsqu’il existe un besoin organisationnel évident et une capacité d’exploitation mature
- Même dans une petite équipe, le découpage peut parfois être pratique pour un service externe d’analyse facile à gérer
- Leçon : n’adoptez les microservices que pour des workloads où l’avantage du découpage est concrètement évident
Guide pratique pour les startups
- Commencez par un monolithe et concentrez-vous sur le travail avec un framework éprouvé
- Un dépôt unique est plus avantageux pour une équipe au début, du point de vue de l’exploitation, de la gestion et de la sécurité
- La simplification de l’environnement de développement local est cruciale ; si cela reste difficile, il faut fournir une documentation détaillée et des vidéos explicatives
- Investissez tôt dans la CI/CD pour automatiser les tâches répétitives et réduire la charge mentale de l’équipe
- Ne découpez de manière sélective que lorsqu’un goulot d’étranglement clair apparaît ; sinon, concentrez-vous sur la modularisation interne du monolithe et le renforcement des tests
- L’objectif prioritaire est de préserver la vitesse de développement
- Leçon : partez de la simplicité et scalez en fonction du besoin réel de séparation
Si vous devez absolument utiliser des microservices
- Évaluer la stack technique et investir dans l’expérience développeur : il faut prévoir de l’automatisation par service, des scripts clairs et des outils de gestion unifiée des déploiements
- Mettre en place des protocoles de communication fiables et standardisés entre services : cohérence des schémas de messages, documentation, gestion des erreurs et autres éléments supplémentaires à implémenter
- Stabiliser l’infrastructure de test : les tests unitaires, d’intégration et E2E doivent pouvoir s’étendre au découpage en services
- Réfléchir aux bibliothèques communes : garder au minimum le code partagé lié à l’observabilité et à la communication afin d’éviter des rebuilds fréquents de tous les services
- Introduire l’observabilité tôt : commencer au minimum par des logs JSON structurés, des identifiants de corrélation et des outils de logging de base
- En conclusion, si l’on accepte la complexité, il est essentiel de concevoir un système maîtrisable avec une discipline rigoureuse
Conclusion
- Une adoption précipitée des microservices ne laisse qu’un fardeau supplémentaire ; il faut donc privilégier avant tout la simplicité
- Il est important de ne pas découper sans point de douleur évident, et de n’ajouter que la complexité minimale nécessaire pour survivre et croître
- La survie d’abord, l’expansion ensuite
10 commentaires
Je suis globalement d’accord avec le propos de l’article original.
Je pense que c’est surtout une question d’expérience de l’organisation.
On peut imaginer qu’on commence par vendre de la nourriture dans un food truck avant de devenir un restaurant.
Dès le départ, l’expérience des parties prenantes est tout simplement insuffisante pour envisager une division du travail et une spécialisation.
Je pense que les startups doivent choisir des approches moins coûteuses afin de prolonger leur durée de survie. Les microservices ne sont absolument pas bon marché. En pratique, lorsqu’on les applique sur le terrain, ils engendrent des coûts considérables. Dans la mesure du possible, concevoir une architecture adaptée à son propre service me semble être un moyen d’obtenir des effets similaires à moindre coût.
Je ne dis pas que les microservices sont mauvais. C’est un modèle qui nécessite beaucoup de moyens.
Je pense qu’il suffit d’avoir seulement deux monolithes : un monolithe purement synchrone et un monolithe purement asynchrone... À mon avis, l’adoption des microservices dépend avant tout de l’ampleur des tables qu’il faut gérer en base de données. Si les tables sont absurdement nombreuses et complexes, il faut envisager une architecture MSA ; si c’est simple, le monolithe est parfaitement adapté.
Quand toutes ces vagues seront passées, comment les générations futures se souviendront-elles de cette époque ?
À l’époque, c’était encore une autre vague...
Je pense que les microservices ont aussi beaucoup d’avantages dans une startup. Déjà, je recommande vraiment les avantages d’utiliser un monorepo.
Je suis d’accord sur le fait qu’à l’ère du développement centré sur l’IA, il est indispensable d’implémenter des composants de petite taille avec une responsabilité unique.
Cela a aussi été brièvement mentionné dans les commentaires, mais l’écosystème beam/otp me paraît vraiment assez souple et intéressant. Dans le cas de Gleam, la bonne syntaxe de Go et de Rust, combinée à la stabilité de beam, en fait un langage assez impressionnant. J’aimerais bien commencer à l’utiliser petit à petit sur de petits projets.
Si on morcelle l’équipe à tout-va, ne serait-ce que se réunir pour échanger des avis devient déjà une charge de travail énorme.
Avis sur Hacker News