Multi-tenant dal primo giorno: perché il SaaS single-tenant è un errore da 5 anni
Single-tenant sembra più sicuro al lancio, poi diventa una ri-architettura di 6-12 mesi tra il cliente 200 e il 500. Pool di default, silo come tier.
La multi-tenancy è un pattern di architettura SaaS in cui una sola istanza applicativa e una sola infrastruttura condivisa servono ogni cliente, con isolamento logico tra account a livello di dati, identità e richiesta. Un team fondatore che sceglie single-tenant per default, di solito perché sembra più sicuro, sta firmando per un progetto di ri-architettura che impegnerà 6-12 mesi di lavoro focalizzato tra il cliente 200 e il cliente 500.
La proposta del single-tenant è intuitiva. Ogni cliente ha il proprio database, il proprio deploy, la propria piccola fortezza. Niente compute condiviso significa niente leak tra account. La logica si rompe al primo contatto con la crescita. Le patch ora girano N volte. Le migrazioni di schema girano N volte. Backup, monitoraggio, observability, turni di on-call: tutto gira N volte. Quando il team si accorge che la unit economics è rotta, il codice ha già assunto la single-tenancy in cento punti, e disfarla è lavoro di ricostruzione, non di refactor.
Perché i team fondatori scelgono single-tenant lo stesso
Tre motivi emergono in quasi ogni kickoff.
Paura della compliance. I prospect enterprise chiedono dell'isolamento dei dati e il team di engineering prende l'interpretazione più difensiva possibile. Un database dedicato sembra più facile da difendere in un questionario di sicurezza che una policy a livello di riga. In pratica, i buyer regolamentati guardano alle prove (report SOC 2, postura di crittografia, audit trail) più che al modello fisico. I pool model con row-level security adeguata superano regolarmente le review enterprise.
Ragionamento prematuro sull'isolamento. L'obiezione del noisy neighbor è reale ma risolvibile. Il catalogo di pattern di Microsoft documenta come la query fuori controllo di un tenant possa degradare l'esperienza di tutti gli altri, e la risposta è rate limit, budget di query, connection pooling e metriche tenant-aware. Non isolamento fisico totale per cliente.
Inerzia da prototipazione veloce. L'MVP è uscito con un solo database Postgres e una sola tabella utenti. Aggiungere multi-tenancy dopo sembra un progetto discreto con uno scope chiaro. Non lo è. Quando viene prioritizzato, ogni endpoint, ogni job e ogni report assume un singolo tenant, e la migrazione deve toccarli tutti.
Cosa ti costa il single-tenant a scala
Tre numeri onesti, presi da writeup di migrazione pubblici e studi di analisti.
Le architetture multi-tenant abbassano il total cost of ownership fino al 40% rispetto al single-tenant, con uno spreco di infrastruttura ridotto di oltre il 30% grazie al pooling delle risorse. Cambiare modello di tenancy dopo il lancio può aggiungere il 20-40% di costo di engineering. Migrare da un design single-tenant a uno schema condiviso dopo 500 clienti richiede tipicamente 6-12 mesi di lavoro di engineering focalizzato.
La tassa nascosta è operativa. Ogni istanza single-tenant ha bisogno della propria verifica di backup, della propria validazione di migrazione, dei propri dashboard di observability e del proprio canale di incident quando le cose vanno male. La superficie di on-call cresce linearmente col numero di clienti. Gli ingegneri passano la settimana a fare deploy, non a costruire feature. Oltre il 70% dei vendor SaaS moderni adotta una qualche forma di multi-tenancy nel 2026 esattamente per questo motivo.
Perché la soluzione ovvia non funziona
"Templatizziamo i deploy" è la pitch che compra al team altri sei mesi di negazione. Funziona per compute e CI, a volte. Non funziona per il database. Le migrazioni di schema su centinaia di database tenant sbattono contro due muri reali. Il primo è la durata: una singola migrazione che gira su 500 database in serie trasforma uno statement da 30 secondi in una finestra di outage da 4 ore. Il secondo è la divergenza: ogni run fallita lascia la flotta in stati inconsistenti, e ragionare su "quale tenant è su quale versione di schema" diventa un lavoro a tempo pieno.
Lo schema-per-tenant dentro un solo database è il secondo compromesso intermedio tentante. Evita la moltiplicazione dei deploy ma ha un soffitto duro. Le prestazioni di Postgres degradano man mano che il numero di schemi cresce oltre qualche migliaio, e il tempo di migrazione scala col numero di schemi. Lo schema-per-tenant funziona bene da 100 a circa 5.000 tenant. Oltre, diventa lo stesso problema operativo con passaggi extra.
Cosa funziona davvero: multi-tenant per default, isolamento come tier
Pool per default, silo a richiesta
Il pattern documentato da AWS e adottato dalla maggior parte dei vendor SaaS moderni è lineare. Spedisci prima un pool model: una sola applicazione, un solo database, ogni riga taggata con un identificatore di tenant. Aggiungi un tier silo dopo, per il piccolo sottoinsieme di clienti enterprise che pagano per risorse dedicate o necessitano residenza dei dati in una regione specifica. Il tier silo è una voce di listino, non l'architettura di default. I modelli ibridi a tier sono ora il pattern dominante nel 2026: infrastruttura pooled per i clienti standard, ambienti dedicati per l'enterprise.
Spingi l'isolamento dentro il database
Il filtraggio a livello di applicazione ("WHERE tenant_id = $current_tenant") funziona finché un giorno uno sviluppatore dimentica di aggiungere la clausola. Allora un endpoint di list espone i dati di ogni tenant a chi è loggato. La soluzione è spingere il filtraggio per tenant sotto l'applicazione: Postgres Row Level Security, valutata dal database a ogni query.
La guida RLS di Supabase documenta il pattern standard: abilita RLS su ogni tabella tenant-scoped, scrivi una policy che confronta tenant_id con un valore preso dal JWT, e lascia che il database lo applichi. Le policy aggiungono un overhead di query, e la service role key è un piede armato, ma una clausola WHERE dimenticata nel codice API non può più causare un leak. Quella garanzia vale l'overhead.
Tagga ogni layer con l'identificatore di tenant
La multi-tenancy fallisce silenziosamente quando l'identificatore di tenant è presente nel database ma manca in log, trace, metriche, code, cache o background job. Aggiungilo ovunque dall'inizio. Ogni log line porta un tenant id. Ogni span porta un tenant id. Ogni metrica è dimensionata per tenant. Ogni chiave Redis ha un namespace per tenant. Ogni background job porta un tenant id nel payload. Tracking dei costi per tenant e debug delle performance per tenant diventano possibili solo se l'identificatore scorre attraverso ogni layer.
Pianifica il noisy neighbor prima di averlo
Tre controlli risolvono la maggior parte del problema: un rate limit di richieste per tenant all'API gateway, un budget di pool di connessioni per tenant al database (Supavisor o pgbouncer), e un timeout di query che aborta tutto ciò che gira troppo a lungo. Aggiungi metriche tenant-aware in modo che il team possa vedere quale cliente sta consumando cosa, e fai emergere una voce di costo per tenant in modo che la unit economics resti leggibile. Il problema del noisy neighbor, come nota il whitepaper AWS sull'isolamento dei tenant, è un problema di equità delle risorse, non un problema di sicurezza. Risolverlo non richiede isolamento fisico.
Definisci la via di fuga al silo presto, costruiscila mai
Decidi prima del lancio cosa offrirà il tuo tier enterprise quando un cliente chiederà isolamento fisico. Database dedicato. Regione dedicata. Chiavi di crittografia gestite dal cliente. Documenta prezzo e processo di attivazione. Non costruirla davvero finché il primo cliente non paga per averla. Il documento di architettura è il deliverable. Il deploy è l'opzione.
Come si presenta nella pratica
Uno stack di partenza ragionevole per un SaaS del 2026, multi-tenant dalla prima riga di codice:
- Una sola istanza Postgres (Supabase, Neon o self-hosted), un solo deploy applicativo.
- Ogni tabella tenant-scoped ha una colonna
tenant_idcon una foreign key atenants. - RLS abilitata su ogni tabella tenant-scoped, con una policy che confronta
tenant_idconauth.jwt() ->> 'tenant_id'. - Il codice applicativo non riferisce mai un tenant id direttamente. Arriva dalla sessione.
- Log, trace, job in coda e chiavi Redis includono tutti il tenant id.
- I rate limit dell'API sono per tenant, non per IP.
- Un job notturno esporta conteggi di righe per tenant, latenza p95 di query e dimensione storage in un metric store, così il team vede un noisy neighbor prima dei clienti.
Un team che spedisce questo dal primo giorno spende più o meno lo stesso tempo di calendario di un team che spedisce single-tenant. La differenza emerge al cliente 50 e decide la sorte dell'azienda al cliente 500. Abbiamo trattato la questione di billing collegata in usage-based pricing per SaaS, dove lo stesso identificatore di tenant diventa la chiave di metering.
Quando il single-tenant ha ancora senso
Tre casi in cui il default single-tenant è la scelta giusta.
Residenza regolamentare stretta. Alcune giurisdizioni richiedono che i dati vivano su infrastruttura dentro un paese specifico, a volte dentro una regione specifica di un provider. Se il profilo dei buyer è dominato da quei vincoli, single-tenant dal primo giorno rimuove l'incertezza.
Crittografia gestita dal cliente. Se il tier enterprise promette chiavi gestite dal cliente e una revoca delle chiavi che di fatto distrugge i dati, quel contratto è più facile da onorare con un database dedicato per cliente.
SaaS sotto i cinque clienti. Un prodotto il cui soffitto sono cinque contratti enterprise può girare come cinque deploy single-tenant per sempre. La matematica si rompe solo sopra qualche decina di clienti, e non ogni prodotto ha quell'ambizione.
Fuori da questi casi, scegliere single-tenant nel 2026 vuol dire scegliere la versione del prodotto che paga il conto più alto tre anni dopo il lancio.
Domande frequenti
- Is multi-tenancy safe for regulated industries like healthcare or finance?
- Yes, when implemented correctly. Most regulated SaaS vendors run multi-tenant infrastructure and pass SOC 2, HIPAA, and ISO 27001 audits routinely. What auditors examine is evidence: encryption at rest and in transit, key management, access controls, audit logs, and proven tenant isolation policies enforced at the database layer. A pool model with Postgres Row Level Security and per-tenant audit trails is auditable. The bar is documentation and proof, not physical separation. The exceptions are jurisdictions that explicitly require data residency or contracts that promise customer-managed encryption keys, which still favor single-tenant for that customer subset.
- How do you migrate an existing single-tenant SaaS to multi-tenant?
- Treat it as a six to twelve month program, not a quarter-long project. Start by adding a tenants table and a tenant_id column to every domain table, with a backfill script that maps each existing customer database to a new tenant id. Then update every query path to filter on tenant_id, ideally enforced at the database layer with Row Level Security so a missed filter cannot leak data. Migrate one customer at a time into the shared infrastructure, validating data isolation on each cutover. Keep the old single-tenant deploys running in parallel until every customer is verified on the new model. Plan a freeze window for the final cutover.
- What is the cost difference between multi-tenant and single-tenant SaaS at 1000 customers?
- Public benchmarks place multi-tenant infrastructure cost at 30 to 60% of the equivalent single-tenant spend at scale. The bigger gap is operational: a multi-tenant SaaS at 1000 customers can be operated by a small platform team because patches, migrations, and observability are unified. The same product on 1000 single-tenant deploys typically requires a dedicated DevOps team purely to keep the fleet healthy. Compound that over three years and the unit economics diverge by orders of magnitude.
Studio
Inizia un progetto.
Un partner unico per aziende, PA, startup e SaaS. Produzione più veloce, tecnologie moderne, costi ridotti. Un team, una fattura.