Vai al contenuto
SaaS

Multi-tenant fin dal primo giorno

Quasi tutte le riscritture SaaS che ci hanno chiamato a salvare risalgono alle stesse tre parole pronunciate dal team originario già nel primo mese: «lo aggiungeremo più avanti». La multi-tenancy,…

Vinay Kumar Verma
Vinay Kumar Verma
Ingegnere del software
PubblicatoQ1 2026
Lettura11 min

Quasi tutte le riscritture SaaS che ci hanno chiamato a salvare risalgono alle stesse tre parole pronunciate dal team originario già nel primo mese: «lo aggiungeremo più avanti». La multi-tenancy, il controllo degli accessi basato sui ruoli, la vera fatturazione. Sembrano cose da innestare una volta che si hanno clienti. È tutto il contrario — sono la forma stessa dell'edificio, e non si possono cambiare le fondamenta una volta alzati i muri senza demolire tutto.

Abbiamo costruito piattaforme che oggi girano in oltre 40 Paesi su un'unica base di codice. La ragione che ha reso ciò possibile è tanto noiosa quanto unanime: tenancy, accesso e fatturazione sono stati decisi fin dal primo giorno, prima della prima funzionalità. Ecco l'aspetto di queste decisioni, e quanto costa rimandarle.

01Perché i team la scansano (e perché è una trappola)

La pressione è reale. Avete un solo cliente pilota, una demo la settimana prossima e un backlog di funzionalità che assomigliano davvero al prodotto. La multi-tenancy è invisibile per quel primo cliente — non può vederla, quindi ha l'aria di un fronzolo superfluo. Il team costruisce così un'applicazione single-tenant «per ora» e promette di generalizzarla in seguito.

La trappola è che «single-tenant per ora» fa trapelare un'ipotesi in ogni livello: che esista esattamente una sola organizzazione al mondo. Questa ipotesi finisce nelle vostre query, nella vostra autenticazione, nelle vostre cache, nei vostri job in background, nei vostri percorsi dei file. Rimuoverla in seguito non è un refactoring — è una riscrittura, perché l'ipotesi non è in un solo posto, è ovunque.

L'asimmetria dei costi

Aggiungere la tenancy fin dal primo giorno vi costa forse due settimane di architettura e disciplina. Aggiungerla al secondo anno — quando avete clienti reali, dati reali e aspettative reali di disponibilità — è una riscrittura di diversi mesi sotto carico, con una migrazione di dati che non avete il diritto di sbagliare. Il lavoro non scompare se lo rimandate. Si accumula.

02Il tenant è la prima colonna

La nostra regola è semplice: ogni riga che appartiene a un cliente porta un tenant_id, e non esiste alcun percorso di codice in grado di eseguire una query senza di esso. Non una convenzione che le persone si ricordano — un vincolo che il database e il framework impongono, così da rendere l'oblio impossibile anziché semplicemente sconsigliato.

La versione più pulita che usiamo si appoggia sul database stesso. Le policy di sicurezza a livello di riga (row-level security) significano che il confine tra tenant è imposto un livello al di sotto del codice applicativo, là dove un bug dell'ORM o una clausola WHERE dimenticata non può far trapelare i dati di un cliente verso un altro. L'applicazione imposta il tenant corrente sulla connessione; il database si rifiuta di restituire qualsiasi altra cosa.

postgres · row-level security
-- the boundary lives below the app, not inside it
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation ON orders
  USING (tenant_id = current_setting('app.tenant')::uuid);

-- app sets the tenant per request; a forgotten WHERE
-- clause now returns zero rows instead of someone else's data
SET app.tenant = 'a91f…';
SELECT * FROM orders;   -- only this tenant's orders, always

Questa singola decisione rimuove dalla vostra lista delle preoccupazioni, e in modo permanente, un'intera categoria di bug catastrofici — la fuga di dati tra tenant. Sono i due giorni di lavoro a più alto effetto leva dell'intero progetto.

Il bug più costoso in SaaS è quello che mostra a un cliente i dati di un altro cliente. Progettate l'architettura perché non possa accadere, non perché sia improbabile.

— Sull'isolamento come vincolo

03Il RBAC non è una pagina di impostazioni

Il secondo «più avanti» che si trasforma in riscrittura è il controllo degli accessi. I team rilasciano con un mondo implicito a due ruoli — admin e utente — codificato a mano in istruzioni if sparse per tutta la base di codice. Poi un cliente enterprise chiede un ruolo «solo fatturazione», o un «revisore in sola lettura», e scoprite logica di permessi in duecento punti.

Modelliamo i permessi come dati fin dall'inizio: i ruoli, i permessi e le assegnazioni tra loro vivono in tabelle, e ogni azione protetta pone una domanda a un'unica autorità centrale: «questo attore può fare questa cosa su questa risorsa, in questo tenant?». Aggiungere un ruolo diventa una riga, non una release. È ciò che permette a una piattaforma di dire sì all'organigramma del cliente enterprise senza toccare il codice applicativo.

  • I permessi sono verbi su risorseinvoice:read, invoice:void — non livelli vaghi come «manager».
  • I ruoli sono insiemi di permessi che un tenant può comporre, così che due clienti possano intendere cose diverse con «admin».
  • Ogni verifica passa per un'unica porta. Una logica di autorizzazione in un solo punto è verificabile; istruzioni if sparse sono una passività.

04La fatturazione è un prodotto, non tubatura

La fatturazione è il punto in cui «lo aggiungeremo più avanti» fa più male, perché nel momento in cui la aggiungete avete clienti con accordi stretti con una stretta di mano, dati incoerenti su chi deve cosa, e nessun concetto pulito di abbonamento. Recuperare la fatturazione significa riconciliare denaro, ed è l'unico punto in cui un bug non è solo imbarazzante — è un rimborso, una controversia o un problema di conformità.

Progettiamo il modello di fatturazione insieme al modello di tenant: piani, abbonamenti, consumo, fatture e il ciclo di vita che li collega. Anche se i primi clienti vengono fatturati manualmente, il modello di dati è presente fin dal primo giorno, così che attivare in seguito piani self-service è una funzionalità, non una migrazione di tutto lo storico del vostro fatturato.

40+Paesi in produzione

Una base di codice, un modello di deployment, molti tenant.

1Base di codice

Nessun fork per cliente da mantenere o da lasciar divergere.

0Fughe tra tenant

Isolamento imposto a livello di database, non per convenzione.

05Quaranta Paesi, un'unica base di codice

Raggiungere oltre 40 Paesi ha l'aria di una storia di scalabilità. In realtà è una storia di configurazione. La piattaforma non ha rami di codice specifici per ciascun Paese — ha un modello di tenant abbastanza ricco da esprimere come dati ciò che differisce da una regione all'altra: valuta, regole fiscali, lingua, formati di data, dicitura legale su una fattura.

Quando il confine tra «codice» e «configurazione» è tracciato correttamente fin dal primo giorno, un nuovo Paese è un'attività di onboarding, non un progetto di ingegneria. Quando è tracciato male, ogni nuovo mercato è un fork, e in meno di un anno vi ritrovate a mantenere una dozzina di versioni sottilmente diverse della stessa applicazione e a rilasciare ogni correzione una dozzina di volte. Il risultato «un'unica base di codice» discende da decisioni prese prima del primo cliente.

Il vero guadagno

Il beneficio di farlo fin dal primo giorno non è visibile nel primo mese — è visibile al terzo anno, quando rilasciate una funzionalità una sola volta e 40 Paesi la ricevono simultaneamente, mentre il vostro concorrente single-tenant la sta ancora fondendo nel suo settimo fork cliente.

06La checklist del primo giorno

Se avviate una piattaforma SaaS questo trimestre, ecco le decisioni da prendere prima di scrivere la minima funzionalità — non perché siano urgenti, ma perché sono irreversibili:

  1. Mettete un tenant_id su tutto e imponetelo al di sotto dell'applicazione. Sicurezza a livello di riga o equivalente. Rendete una query cross-tenant impossibile, non improbabile.
  2. Modellate i permessi come dati. Ruoli e assegnazioni in tabelle, un'unica porta di autorizzazione centrale. Aggiungere un ruolo dovrebbe essere una riga.
  3. Costruite presto il modello di dati della fatturazione. Piani, abbonamenti, fatture — anche se all'inizio fatturate a mano. Non recuperate il denaro a posteriori.
  4. Separate il codice dalla configurazione. Tutto ciò che varia in base al cliente o alla regione è un dato. Il Paese numero 41 dovrebbe essere un modulo di onboarding.
  5. Scrivete per primo il percorso di provisioning del tenant. Creare in modo pulito un nuovo tenant, con valori predefiniti sensati, è la vostra operazione più eseguita. Automatizzatela fin dal primo giorno.

Nulla di tutto ciò è esotico. Sono alcune settimane di disciplina all'inizio in cambio del non dover mai fare la riscrittura. I team che raggiungono 40 Paesi su un'unica base di codice non sono stati fortunati — si sono semplicemente rifiutati di dire «più avanti» riguardo alle tre cose che non possono essere aggiunte più avanti.

Vinay Kumar Verma
Scritto da

Vinay Kumar Verma

Ingegnere del software

Vinay lavora sulle fondamenta delle piattaforme — multi-tenancy, identità e fatturazione — l'architettura che consente a un'unica base di codice di servire più mercati senza creare fork. Ha costruito i livelli di tenancy, RBAC e fatturazione alla base di piattaforme SaaS attive in oltre 40 paesi.

Hai un progetto in mente?

Raccontacelo — ti risponderemo entro un giorno lavorativo con una valutazione onesta su fit e scope.