Architecturer un SaaS Laravel évolutif
La plupart des SaaS Laravel commencent mono-tenant, avec une table tenants plus tard. Ça tient jusqu’à ce que jobs, caches et fichiers fuient entre clients. L’isolation est une décision produit, pas un middleware collé après.
L’isolation est le produit
Je traite la tenancy comme une frontière dure : données, files, stockage et config. Une colonne tenant_id ne suffit pas si un job peut encore voir les mauvaises lignes.
Sur des plateformes comme BROC ServiceOS, la question n’est pas le package. C’est : que se passe-t-il si la facture du tenant A tourne pendant qu’on restaure B. Sans réponse, ce n’est pas encore un SaaS.
Files, cache et fichiers
Horizon, Redis et S3 ne sont pas du décor. Chaque job porte le tenant. Chaque clé de cache est préfixée. Chaque upload a un propriétaire.
Si vous sautez ça, vous débuggerez des données « aléatoires » en prod. Ce n’est jamais aléatoire. C’est une frontière manquante.
La facturation à côté du tenant
Les offres doivent mapper des limites réellement appliquées : sièges, sites, volume API — pas un PDF de fonctionnalités. La facturation vit à côté du tenant.
Depuis Tanger je livre les SaaS Laravel comme ça : une réécriture après le deuxième client coûte plus cher qu’un modèle d’isolation clair dès le premier jour.
À retenir
- Décidez l’isolation avant les packages.
- Jobs, cache et fichiers doivent porter le tenant.
- Facturez des limites que vous appliquez vraiment.
FAQ
Faut-il un package multi-tenant dès le jour 1 ?
Un package seulement après avoir décrit l’isolation : base, files, fichiers. Le package n’invente pas une frontière que vous n’avez pas conçue.
Une base ou une base par tenant ?
Une base et un scoping strict au début. Séparez plus tard si conformité, restore ou voisins bruyants l’imposent — pas un article de blog.