Vai al contenuto
Blog

SaaS

Pattern di architettura multi-tenant per SaaS

Row-level, schema-per-tenant o database-per-tenant? Una guida per scegliere un'architettura multi-tenant che scala senza bloccare l'evoluzione futura.

Di Pykero Agency · Engineering team8 lug 20266 min di lettura
Diagramma astratto di nodi database e partizioni tenant isolate con connessioni luminose

La multi-tenancy è la decisione che plasma silenziosamente l'intero backend SaaS. Presa bene, permette di scalare agevolmente fino a migliaia di account. Presa male, si finisce a riscrivere il data layer sotto carico, nel pieno della crescita, con i clienti che guardano. La buona notizia: per la maggior parte dei prodotti la risposta giusta è più semplice di quanto internet lasci intendere.

I tre modelli

Esistono tre approcci canonici per isolare i tenant, ciascuno con un diverso equilibrio tra isolamento e costo operativo:

  1. Row-level (schema condiviso). Ogni tabella ha una colonna tenant_id e ogni query la filtra. Un unico database, un unico schema, tutti i tenant insieme.
  2. Schema-per-tenant. Ogni tenant riceve il proprio schema PostgreSQL all'interno di un database condiviso. Isolamento più robusto, ma più oggetti da gestire.
  3. Database-per-tenant. Ogni tenant dispone di un database o un'istanza dedicata. Isolamento massimo, peso operativo massimo.

Perché il row-level vince per la maggior parte dei SaaS

Per la stragrande maggioranza dei prodotti B2B SaaS, la multi-tenancy a row-level è il punto di partenza corretto. È la soluzione meno costosa da gestire, la più semplice su cui eseguire le migrazioni e scala molto più di quanto i founder si aspettino. L'obiezione è sempre "ma l'isolamento", e Postgres ha una risposta solida.

La Row-Level Security (RLS) consente al database stesso di garantire che una query veda esclusivamente le righe del proprio tenant. Con Supabase, RLS è il modello nativo: si definisce una policy una volta sola e, anche in presenza di un bug nel codice, i dati non possono trapelare tra tenant diversi. Combinato con un tenant_id su ogni tabella e un indice che lo include come colonna iniziale, questo pattern serve comodamente basi clienti di grandi dimensioni.

Un avvertimento derivato dall'esperienza diretta: scrivere le policy RLS in modo che le funzioni ausiliarie vengano eseguite una volta per query, non una volta per riga. Una policy che rivaluta una lookup per ogni riga trasformerà silenziosamente endpoint veloci in endpoint lenti man mano che le tabelle crescono. Incapsulare il controllo in modo che il planner lo esegua come init-plan.

Quando optare per un isolamento più robusto

Si passa a un modello più forte in modo deliberato, non per riflesso:

  • Isolamento normativo o contrattuale: un cliente richiede che i propri dati risiedano in un database fisicamente separato.
  • Rischio di noisy-neighbor: il carico di lavoro di un tenant di grandi dimensioni degrada le prestazioni per tutti gli altri.
  • Personalizzazione per tenant: gli schemi divergono realmente, non solo i dati.

Anche in questi casi, un approccio ibrido funziona bene: mantenere la maggior parte dei tenant a row-level e promuovere solo gli account più grandi o più sensibili a database dedicati.

Progettare per il modello fin dal primo giorno

Qualunque sia la scelta, è fondamentale incorporarla fin dall'inizio:

  • Inserire tenant_id su ogni tabella di dominio e usarlo come colonna iniziale negli indici compositi.
  • Non fidarsi mai del client per determinare il tenant: derivarlo dalla sessione autenticata.
  • Applicare l'isolamento a livello di database, non solo a livello applicativo, così una clausola WHERE dimenticata non può causare una fuga di dati.
  • Rendere il provisioning dei tenant un unico percorso di codice testato.

L'errore che fa davvero male non è scegliere il modello "sbagliato": è lasciare la tenancy implicita e disperdere la logica di isolamento in tutto il codebase. Centralizzarla, applicarla nel database e si mantiene la libertà di evolvere.

Se si sta progettando un backend multi-tenant e si cerca un partner che abbia già messo in produzione sistemi PostgreSQL con RLS su scala reale, contattateci.

SaaSarchitecturePostgreSQLscaling

Come può aiutare Pykero

Servizi collegati a questo articolo.

State costruendo qualcosa di simile?

Pykero Agency progetta e rilascia prodotti web, mobile, SaaS e AI pronti per la produzione.

Parliamone

Discussion

Be the first to comment.

Letture correlate