Découvrez comment les bases de données multi‑locataires influent sur la sécurité et les performances, les risques principaux (isolement, voisin bruyant) et des contrôles pratiques pour protéger les locataires et garantir la rapidité.

Une base de données multi‑locataire est une configuration où plusieurs clients (locataires) partagent le même système de base de données — le même serveur de base, le même stockage sous‑jacent et souvent le même schéma — tandis que l'application garantit que chaque locataire ne peut accéder qu'à ses propres données.
Pensez‑y comme à un immeuble d'appartements : tout le monde partage la structure et les services, mais chaque locataire a son unité verrouillée.
Dans une approche mono‑locataire, chaque client obtient des ressources de base de données dédiées — par exemple sa propre instance de base de données ou son propre serveur. L'isolation est plus simple à appréhender, mais généralement plus coûteuse et plus lourde à gérer quand le nombre de clients augmente.
Avec la multi‑location, les locataires partagent l'infrastructure, ce qui peut être efficace — mais cela signifie aussi que votre conception doit volontairement appliquer des frontières.
Les entreprises SaaS optent souvent pour la multi‑location pour des raisons pratiques :
La multi‑location n'est pas automatiquement « sécurisée » ou « rapide ». Les résultats dépendent de choix comme la façon dont les locataires sont séparés (schéma, lignes ou bases), la manière dont le contrôle d'accès est appliqué, la gestion des clés de chiffrement, et comment le système empêche qu'un locataire ralentisse les autres.
Le reste de ce guide se concentre sur ces choix de conception — car dans les systèmes multi‑locataires, la sécurité et les performances sont des fonctionnalités que vous construisez, pas des hypothèses héritées.
La multi‑location n'est pas un choix unique — c'est un spectre de partage d'infrastructure. Le modèle choisi définit votre frontière d'isolation (ce qui ne doit jamais être partagé), et cela affecte directement la sécurité, l'isolation des performances et les opérations quotidiennes.
Chaque locataire obtient sa propre base de données (souvent sur le même serveur ou cluster).
Frontière d'isolation : la base de données elle‑même. C'est généralement l'histoire d'isolation la plus propre parce qu'un accès inter‑locataires nécessite typiquement de franchir la frontière de la base.
Compromis opérationnels : plus lourd à gérer à grande échelle. Les mises à jour et migrations de schéma peuvent devoir être exécutées des milliers de fois, et le pooling de connexions peut se compliquer. Les sauvegardes/restaurations sont simples au niveau du locataire, mais le stockage et la gestion peuvent croître rapidement.
Sécurité & tuning : généralement le plus simple à sécuriser et optimiser par client ; adapté quand les locataires ont des exigences de conformité différentes.
Les locataires partagent une base de données, mais chacun a son propre schéma.
Frontière d'isolation : le schéma. C'est une séparation significative, mais elle repose sur des permissions et des outils corrects.
Compromis opérationnels : les mises à jour et migrations restent répétitives, mais moins lourdes que la base‑par‑locataire. Les sauvegardes sont plus délicates : beaucoup d'outils prennent la base comme unité de sauvegarde, donc les opérations au niveau du locataire peuvent nécessiter des exports de schéma.
Sécurité & tuning : plus facile à isoler que des tables partagées, mais il faut être discipliné sur les privilèges et empêcher que des requêtes réfèrent le mauvais schéma.
Tous les locataires partagent une base et un schéma, mais chaque locataire a des tables séparées (par ex. orders_tenant123).
Frontière d'isolation : l'ensemble de tables. Cela peut fonctionner pour un petit nombre de locataires, mais c'est peu scalable : surcharge des métadonnées, scripts de migration ingérables, et planification de requêtes dégradée.
Sécurité & tuning : les permissions peuvent être précises, mais la complexité opérationnelle est élevée et il est facile de faire des erreurs lors de l'ajout de nouvelles tables ou fonctionnalités.
Tous les locataires partagent les mêmes tables, différenciées par une colonne tenant_id.
Frontière d'isolation : votre couche de requête et de contrôle d'accès (souvent la sécurité au niveau des lignes). Ce modèle est efficace opérationnellement — un schéma à migrer, une stratégie d'index unique — mais il est le plus exigeant en matière de sécurité et d'isolation des performances.
Sécurité & tuning : le plus difficile à réussir car chaque requête doit être consciente du locataire, et le problème du voisin bruyant est plus probable sauf si vous ajoutez limitation des ressources et indexation soignée.
Une règle utile : plus vous partagez, plus les mises à jour sont simples — mais plus vous avez besoin de rigueur dans les contrôles d'isolation et d'isolation des performances.
La multi‑location ne signifie pas seulement « plusieurs clients dans une base ». Elle change votre modèle de menace : le plus grand risque passe des intrusions externes à des utilisateurs autorisés qui voient accidentellement (ou délibérément) les données d'un autre locataire.
L'authentification répond à « qui êtes‑vous ? ». L'autorisation répond à « à quoi avez‑vous droit ? ». Dans une base multi‑locataire, le contexte du locataire (tenant_id, account_id, org_id) doit être appliqué lors de l'autorisation — et non traité comme un filtre optionnel.
Une erreur fréquente est de supposer qu'une fois qu'un utilisateur est authentifié et que vous « connaissez » son locataire, l'application gardera naturellement les requêtes séparées. En pratique, la séparation doit être explicite et appliquée à un point de contrôle cohérent (par ex. politiques en base ou une couche de requête obligatoire).
La règle la plus simple et la plus importante : chaque SELECT et chaque INSERT/UPDATE/DELETE doit être scopié à exactement un locataire.
Cela s'applique à :
Si le scoping de locataire est optionnel, il finira par être omis.
Les fuites inter‑locataires proviennent souvent de petites erreurs routinières :
tenant_idLes tests tournent typiquement sur des jeux de données minuscules et des hypothèses propres. La production ajoute la concurrence, les retries, les caches, les données mixtes et des cas limites réels.
Une fonctionnalité peut passer les tests parce qu'un seul locataire existe dans la base de test, ou parce que les fixtures n'incluent pas d'IDs qui se chevauchent entre locataires. Les conceptions les plus sûres rendent difficile d'écrire une requête non scopiée, plutôt que de compter sur les relectures.
Le risque central dans une base multi‑locataire est simple : une requête qui oublie de filtrer par locataire peut exposer les données d'un autre. Des contrôles d'isolation robustes supposent que des erreurs arriveront et rendent ces erreurs inoffensives.
Chaque enregistrement appartenant à un locataire devrait porter un identifiant de locataire (par ex. tenant_id) et votre couche d'accès aux données devrait toujours scoper les lectures et écritures avec celui‑ci.
Un pattern pratique est « contexte du locataire d'abord » : l'application résout le locataire (depuis le sous‑domaine, l'ID d'organisation ou les claims du token), le stocke dans le contexte de la requête, et votre code d'accès aux données refuse de s'exécuter sans ce contexte.
Garde‑fous utiles :
tenant_id dans les clés primaires/uniques quand approprié (pour éviter les collisions entre locataires).tenant_id pour empêcher la création accidentelle de relations inter‑locataires.Là où c'est supporté (notamment PostgreSQL), la sécurité au niveau des lignes peut déplacer les vérifications de locataire dans la base. Les politiques peuvent restreindre chaque SELECT/UPDATE/DELETE pour que seules les lignes correspondant au locataire courant soient visibles.
Cela réduit la dépendance au fait que « chaque développeur se souvient du WHERE », et peut aussi protéger contre certaines injections ou mauvais usages d'ORM. Considérez la RLS comme un second verrou, pas comme le seul verrou.
Si des locataires ont des données très sensibles ou des exigences de conformité strictes, séparer par schéma (ou même par base) peut réduire le rayon d'impact. Le compromis est une surcharge opérationnelle accrue.
Concevez les permissions pour que la valeur par défaut soit « pas d'accès » :
Ces contrôles fonctionnent mieux ensemble : scoping fort, politiques applicables en base quand possible, et privilèges conservateurs qui limitent les dégâts quand quelque chose échappe.
Le chiffrement est un des rares contrôles qui aide même si d'autres couches d'isolation échouent. Dans un datastore partagé, l'objectif est de protéger les données en transit, au repos, et démontrer pour quel locataire l'application agit.
Pour les données en transit, exigez TLS pour chaque étape : client → API, API → base de données, et pour les appels internes. Faites‑le appliquer au niveau de la base quand c'est possible (par ex. rejeter les connexions non‑TLS) pour éviter que des « exceptions temporaires » ne deviennent permanentes.
Pour les données au repos, utilisez le chiffrement géré du disque ou de la base (TDE, chiffrement des backups). Cela protège contre la perte de média, l'exposition de snapshots et certaines compromissions d'infrastructure — mais cela n'empêchera pas une requête boguée de retourner des lignes d'un autre locataire.
Une clé de chiffrement partagée est plus simple (moins de clés à faire tourner), mais le rayon d'impact est grand : si la clé fuit, tous les locataires sont exposés.
Les clés par locataire réduisent le rayon d'impact et répondent parfois à des exigences clients, mais ajoutent de la complexité : cycle de vie des clés, rotations et workflows de support (par ex. si un locataire désactive sa clé).
Un compromis pratique est le chiffrement par enveloppe : une clé maître chiffre des clés de données par locataire, ce qui rend les rotations gérables.
Stockez les identifiants de base dans un gestionnaire de secrets, pas dans des variables d'environnement en configurations longue durée. Préférez des identifiants à courte durée ou une rotation automatique, et scopez l'accès par rôle de service pour qu'une compromission dans un composant n'ouvre pas automatiquement toutes les bases.
Traitez l'identité du locataire comme critique pour la sécurité. N'acceptez jamais un tenant_id brut du client comme « vérité ». Lieuez le contexte du locataire à des tokens signés et à des vérifications serveur, et validez‑le à chaque requête avant tout appel à la base.
La multi‑location change ce que « normal » veut dire. Vous ne surveillez pas seulement une base — vous surveillez de nombreux locataires partageant le même système, où une erreur peut devenir une exposition inter‑locataires. Une bonne auditabilité et surveillance réduisent la probabilité et le rayon d'impact des incidents.
Au minimum, consignez chaque action qui peut lire, modifier ou accorder l'accès aux données d'un locataire. Les événements d'audit les plus utiles répondent à :
tenant_id comme champ de première classe (jamais inféré après coup)Consignez aussi les actions administratives : création de locataires, changement de politiques d'isolation, modification des règles RLS, rotation de clés, et changement de chaînes de connexion.
La surveillance doit détecter des patterns improbables en usage SaaS :
tenant_id, ou pics soudains d'erreurs « tenant mismatch »Rattachez des runbooks actionnables aux alertes : quoi vérifier, comment contenir, et qui appeler.
Traitez l'accès privilégié comme un changement en production. Utilisez des rôles au moindre privilège, des identifiants courts, et des approbations pour les opérations sensibles (changements de schéma, exports de données, éditions de politiques). Pour les urgences, conservez un compte break‑glass strictement contrôlé : identifiants séparés, ticket/approbation obligatoire, accès limité dans le temps et journalisation renforcée.
Fixez la rétention selon les besoins de conformité et d'enquête, mais restreignez l'accès pour que le support ne voie que les logs de son locataire. Lorsqu'un client demande un export d'audit, fournissez des rapports filtrés par locataire plutôt que des logs bruts partagés.
La multi‑location améliore l'efficacité en laissant plusieurs clients partager la même infra DB. Le compromis est que les performances deviennent une expérience partagée : l'activité d'un locataire peut affecter les autres, même si leurs données sont isolées.
Un « voisin bruyant » est un locataire dont l'activité est si lourde (ou si en rafale) qu'il consomme plus que sa part de ressources partagées. La base n'est pas « cassée » — elle est simplement occupée à traiter ce travail, et les autres locataires attendent.
Imaginez un immeuble où une unité utilise plusieurs douches et la machine à laver en même temps : la pression d'eau baisse pour tous.
Même quand chaque locataire a ses propres lignes ou schémas, de nombreux composants critiques pour la performance restent partagés :
Quand ces pools partagés sont saturés, la latence augmente pour tous.
Beaucoup de charges SaaS arrivent en rafales : un import, des rapports de fin de mois, une campagne marketing, un cron qui tourne à l'heure pile.
Les rafales peuvent créer des « embouteillages » dans la DB :
Même si la rafale ne dure que quelques minutes, elle peut provoquer des délais résiduels pendant que les files se vident.
Du point de vue client, les problèmes de voisin bruyant semblent aléatoires et injustes. Symptômes fréquents :
Ces signes indiquent qu'il faut des techniques d'isolation des ressources plutôt que seulement « plus de matériel ».
La multi‑location fonctionne mieux quand un client ne peut pas « emprunter » plus que sa part de capacité DB. L'isolation des ressources est un ensemble de garde‑fous qui empêche un locataire lourd de ralentir tout le monde.
Un mode d'échec fréquent est le nombre de connexions non limité : un pic d'un locataire ouvre des centaines de sessions et affame la DB.
Posez des plafonds dans deux endroits :
Même si votre DB ne peut pas appliquer directement « connexions par locataire », vous pouvez l'approximer en routant chaque locataire via un pool dédié ou partitionné.
La limitation de débit favorise l'équité dans le temps. Appliquez‑la près de la périphérie (API gateway/app) et, quand disponible, dans la base (groupes de ressources / workload management).
Exemples :
Protégez la base contre les requêtes « runaway » :
Ces contrôles doivent échouer proprement : renvoyer une erreur claire et proposer retry/backoff.
Déplacez la charge lecture loin du primaire :
Le but n'est pas seulement la vitesse — c'est aussi réduire la contention CPU/verrous pour que les locataires bruyants aient moins de leviers d'impact.
Les problèmes de performance en multi‑location ressemblent souvent à « la DB est lente », mais la cause racine est souvent le modèle de données : comment les données du locataire sont indexées, filtrées et physiquement organisées. Un bon modèle rend les requêtes scopiées naturellement rapides ; un mauvais modèle force la DB à travailler trop dur.
La plupart des requêtes SaaS incluent un identifiant de locataire. Modelez‑le explicitement (par ex. tenant_id) et concevez des index qui commencent par celui‑ci. En pratique, un index composite comme (tenant_id, created_at) ou (tenant_id, status) est bien plus utile qu'un index sur created_at seul.
Ceci s'applique aussi aux unicités : si les emails sont uniques par locataire, imposez (tenant_id, email) plutôt qu'une contrainte globale sur email.
Un pattern de requête lente fréquent est un scan inter‑locataires accidentel : une requête qui oublie le filtre de locataire et balaie une large portion de la table.
Rendez le chemin sûr facile :
Le partitionnement réduit la quantité de données considérées par chaque requête. Partitionnez par locataire quand certains locataires sont gros et hétérogènes. Partitionnez par temps quand l'accès est majoritairement récent (événements, logs, factures), souvent avec tenant_id en colonne d'index principale à l'intérieur de chaque partition.
Pensez au sharding quand une seule base ne suffit plus au débit de pointe, ou quand le travail d'un locataire menace les autres.
Les « hot tenants » représentent un volume disproportionné de lectures/écritures, de contention sur les verrous ou d'index surdimensionnés.
Détectez‑les via le suivi du temps de requête par locataire, des lignes lues et des taux d'écriture. Quand un locataire domine, isolez‑le : migrez‑le vers un shard/base séparée, scindez les tables par locataire, ou introduisez des caches dédiés et des limites pour préserver la vitesse des autres.
La multi‑location échoue rarement parce que la base « ne peut pas le faire ». Elle échoue quand les opérations quotidiennes laissent de petites incohérences se transformer en failles de sécurité ou régressions de performance. L'objectif est de faire du chemin sûr le comportement par défaut pour chaque changement, job et déploiement.
Choisissez un identifiant canonique (ex. tenant_id) et utilisez‑le partout : tables, index, logs et APIs. La cohérence réduit les erreurs de sécurité (requêter le mauvais locataire) et les surprises de performance (index composites manquants).
Garde‑fous pratiques :
tenant_id dans tous les chemins d'accès principaux (queries, repositories, scopes ORM)tenant_id pour les recherches courantestenant_id, contraintes CHECK) pour détecter les mauvaises écritures tôtLes workers asynchrones sont une source fréquente d'incidents inter‑locataires car ils s'exécutent « hors » du contexte de la requête qui a établi le contexte du locataire.
Bonnes pratiques opérationnelles :
tenant_id dans chaque payload de job ; ne comptez pas sur un contexte ambianttenant_id au début/fin du job et à chaque retry pour enquêter rapidementLes migrations de schéma et de données doivent être déployables sans un rollout parfaitement synchronisé.
Utilisez des changements progressifs :
Ajoutez des tests négatifs automatiques qui tentent délibérément d'accéder aux données d'un autre locataire (lecture et écriture). Traitez‑les comme des bloqueurs de release.
Exemples :
tenant_id incorrect et vérifier l'échec netLes sauvegardes sont faciles à décrire (« copier la base ») et étonnamment difficiles à exécuter en sécurité dans une base multi‑locataire. Au moment où de nombreux clients partagent des tables, il faut un plan pour récupérer un locataire sans exposer ou écraser les autres.
Une sauvegarde complète de la base reste la base pour la reprise après sinistre, mais elle ne suffit pas pour les cas d'assistance quotidiens. Approches courantes :
tenant_id) pour restaurer les données d'un seul locataireSi vous comptez sur des exports logiques, traitez le job d'export comme du code de production : il doit appliquer l'isolation (par ex. via RLS) plutôt que de faire confiance à un WHERE écrit une fois.
Les requêtes de confidentialité (export, suppression) sont des opérations au niveau locataire qui touchent sécurité et performance. Construisez des workflows répétables et audités pour :
Le plus grand risque n'est pas un hacker — c'est un opérateur pressé. Réduisez les erreurs humaines avec des garde‑fous :
tenant_id avant l'importAprès un exercice de reprise, n'arrêtez pas à « l'app est up ». Exécutez des contrôles automatisés qui confirment l'isolation des locataires : requêtes d'échantillonnage, revue des logs d'audit et vérification ponctuelle que les clés et rôles d'accès sont toujours correctement scopiés.
La multi‑location est souvent le meilleur choix par défaut pour le SaaS, mais ce n'est pas une décision permanente. En fonction de l'évolution du produit et du mix client, l'approche « une seule base partagée » peut commencer à engendrer des risques métier ou ralentir la livraison.
Réfléchissez à passer à plus d'isolation quand vous voyez régulièrement :
Vous n'avez pas à choisir entre « tout partagé » et « tout dédié ». Approches hybrides communes :
Plus d'isolation signifie généralement plus de coûts d'infrastructure, plus de surcharge opérationnelle (migrations, monitoring, on‑call) et plus de coordination de release (changements de schéma à travers plusieurs environnements). Le compromis est des garanties de performance plus claires et des conversations de conformité simplifiées.
Si vous évaluez des options d'isolation, consultez les guides associés dans /blog ou comparez les plans et options de déploiement sur /pricing.
Si vous voulez prototyper un SaaS rapidement et tester tôt les hypothèses multi‑locataires (scoping du locataire, schémas compatibles RLS, throttling et workflows opérationnels), une plateforme de type « vibe‑coding » comme Koder.ai peut vous aider à créer une app React + Go + PostgreSQL depuis le chat, itérer en mode planification et déployer avec snapshots et rollback — puis exporter le code source quand vous êtes prêt à durcir l'architecture pour la production.
Une base de données multi‑locataire est une configuration où plusieurs clients partagent la même infrastructure de base de données (souvent le même schéma), tandis que l'application et/ou la base de données s'assurent que chaque locataire n'accède qu'à ses propres données. L'exigence centrale est une délimitation stricte du locataire sur chaque lecture et écriture.
La multi‑location est souvent choisie pour :
Le compromis est que vous devez construire volontairement des garde‑fous pour l'isolation et les performances.
Les modèles courants (du plus isolé au plus partagé) sont :
Le risque principal bascule vers l'accès croisé entre locataires causé par des erreurs de routine, pas seulement les attaquants externes. Le contexte du locataire (par ex. tenant_id) doit être traité comme une exigence d'autorisation, pas un simple filtre optionnel. Il faut aussi tenir compte des réalités de production : concurrence, caches, retries et workers en arrière‑plan.
Les causes les plus fréquentes incluent :
tenant_idConcevez des garde‑fous pour rendre les requêtes non‑scopées difficiles (ou impossibles).
La sécurité au niveau des lignes (RLS) déplace la vérification du locataire dans la base via des politiques restreignant SELECT/UPDATE/DELETE aux lignes correspondant au locataire courant. Elle réduit la dépendance au fait que « tout le monde se souvienne du WHERE », mais doit être couplée à un scoping côté application, au principe du moindre privilège et à des tests solides. Traitez la RLS comme un verrou supplémentaire, pas comme la seule protection.
Un socle pratique comprend :
tenant_id canonique sur les tables appartenant au locatairetenant_idL'objectif : que les erreurs échouent en toute sécurité.
Le chiffrement aide mais couvre des risques différents :
Traitez aussi l'identité du locataire comme critique : ne faites pas confiance à un brut venant du client ; liez‑le à des tokens signés et des validations serveur.
Le problème du « voisin bruyant » survient quand un locataire consomme une part excessive des ressources partagées (CPU, mémoire, I/O, connexions), augmentant la latence pour les autres. Mécanismes pratiques :
L'objectif est l'équité, pas seulement le débit brut.
Passez à une isolation plus forte si :
Options hybrides : extraire quelques gros clients vers des bases/clusters dédiés, offres par paliers (partagé vs dédié), ou isoler l'analytics/reporting.
Ces choix entraînent des coûts infra et opérationnels plus élevés mais offrent de meilleures garanties de performance et de conformité.
tenant_id) : opérations simplifiées, plus difficile à sécuriser et optimiser.Votre choix définit la frontière d'isolation et la charge opérationnelle.
tenant_id