Att bygga en SaaS-produkt handlar i grunden om en arkitekturfråga som du måste besvara innan första raden affärslogik skrivs: hur ska olika kunder (tenants) dela – eller inte dela – samma infrastruktur och data? Väljer du fel modell tidigt blir kostnaden för att byta ofta enorm. Den här guiden går igenom de etablerade isoleringsmodellerna, hur du implementerar robust dataisolering med Row-Level Security, hur du skalar utan att en kund drar ner alla andra, och hur du onboardar nya tenants på ett kontrollerat sätt.

Vad multitenancy egentligen är

Multitenancy betyder att en och samma applikationsinstans betjänar flera kunder, där varje kund är en tenant. Tenants ska aldrig kunna se varandras data, men de delar kodbas och – beroende på modell – delar de också databaser, scheman eller hela miljöer. Motsatsen är single-tenant, där varje kund får en egen, dedikerad installation.

I praktiken är frågan sällan binär. AWS beskriver tre välkända modeller i sin SaaS Lens: pool (alla tenants delar resurser), silo (dedikerade resurser per tenant) och bridge (en hybrid där vissa delar delas och andra isoleras). De flesta mogna SaaS-plattformar landar i någon form av bridge.

Shared vs isolated: tre databasmodeller

Pooled – delad databas, delat schema

Alla tenants ligger i samma tabeller och varje rad märks med en tenant_id. Isolering sker logiskt via filtrering. Det här är den mest skalbara och kostnadseffektiva modellen och förstahandsvalet för de allra flesta B2B-SaaS i tidig fas. Nackdelarna: den svagaste isoleringen, störst risk för "noisy neighbor" (en tung tenant som påverkar andra) och svårast att uppfylla strikta krav på dataresidens.

Silo – schema eller databas per tenant

Varje tenant får ett eget schema eller en egen databas. Det ger stark isolering, eliminerar noisy neighbor och förenklar regelefterlevnad och dataresidens. Priset är högre driftkomplexitet: migreringar måste köras mot hundratals eller tusentals databasobjekt, och när antalet tenants växer förbi ungefär tusen börjar objektgränser och migreringstider bli ett reellt problem.

Bridge – hybriden

Den vanligaste verkligheten: standardkunder körs poolat medan enterprise-kunder med compliance-krav eller tunga laster får isolerade miljöer. En ny variant som vuxit fram är databas-per-tenant med lätta motorer (till exempel SQLite-baserade edge-databaser) som placerar sig mellan poolat schema och separata fullskaliga databaser.

Bygg rätt från dag ett

Det viktigaste rådet: gör tenant_id till en förstklassig kolumn på varje tenant-ägd tabell – från första migreringen, även om du startar poolat och planerar att bli hybrid senare. Att lägga till tenant_id i efterhand på en produktionsdatabas med riktig data är ett av de mest smärtsamma ingreppen man kan göra.

  • Använd ett UUID som tenant_id. Det undviker gissningsbara sekvenser och gör datamigrering och sammanslagningar enklare.
  • Separera tydligt tenant-scopade tabeller (har tenant_id, ska ha RLS) från globala/delade tabeller (saknar tenant_id).
  • Designa API:et så att tenant-kontext härleds från autentiseringen – aldrig från en parameter klienten kan sätta fritt.

Dataisolering med Row-Level Security

Att förlita sig på att varje query har rätt WHERE tenant_id = ... är en olycka som väntar på att hända – det räcker med en glömd filtrering. Row-Level Security (RLS) i PostgreSQL flyttar isoleringen ner till databasnivå, där den gäller oavsett vilken kod som ställer frågan. AWS lyfter just detta: RLS centraliserar policyn och tar bort bördan från enskilda utvecklare.

Sätta tenant-kontext säkert

Det rekommenderade mönstret är att inte skapa en databasanvändare per tenant, utan att sätta tenant-kontext vid körning. Inuti en transaktion:

  • SET LOCAL app.current_tenant = 'tenant-uuid' – med LOCAL nollställs kontexten automatiskt när transaktionen avslutas. Det är avgörande i poolade anslutningar som återanvänds, annars riskerar nästa request ärva fel tenant.
  • RLS-policyn jämför sedan radens tenant_id mot current_setting('app.current_tenant').

Bygger du på Supabase hämtas tenant_id i stället från användarens JWT. Lagra den i app_metadata, aldrig i user_metadata – det senare kan slutanvändaren själv ändra, vilket öppnar en isoleringslucka. En auth.jwt() -> 'app_metadata' ->> 'tenant_id'-baserad policy ger en ren och svårmanipulerad regel.

Fallgropar att känna till

  • Aktivera RLS på alla tabeller med tenant-data, och använd FORCE ROW LEVEL SECURITY så att även tabellägaren omfattas.
  • Vyer ägda av en superuser-roll kan kringgå RLS helt – en klassisk och farlig miss.
  • Indexera på tenant_id (gärna sammansatt, t.ex. (tenant_id, email)). Ser du seq scans i query-planen saknas troligen index.
  • Lägg till en CI-kontroll som fäller bygget om en tenant-tabell saknar RLS-policy. Det är den enskilt mest värdefulla skyddsmekanismen mot mänskliga misstag.

Skalning och noisy neighbor

Ju mer som delas, desto större chans att en tenants beteende påverkar andra. En enda tenant som kör tunga rapporter kan dra ner svarstider för alla i en poolad miljö. Strategier för att hantera detta:

  • Sharding – fördela tenants över flera databaser eller kluster, ofta med tenant_id som shard-nyckel.
  • Targeted isolation – flytta de tyngsta eller mest känsliga tenanterna till silo medan resten förblir poolade. Det är bridge-modellen i praktiken.
  • Per-tenant-mätning – mät resursförbrukning per tenant. Det krävs både för att hitta noisy neighbors och för att förstå enhetsekonomin. 2026 är detta i princip standard, ofta kompletterat med AI-driven övervakning.
  • Connection pooling som respekterar tenant-kontext – kombinera med SET LOCAL enligt ovan.

Tenant-onboarding

Onboarding är där arkitekturvalet möter verkligheten. En ny tenant ska kunna provisioneras automatiskt och idempotent:

  • Skapa tenant-posten, generera tenant_id och koppla den till administratörsanvändarens app_metadata/JWT-claims.
  • I silo-/bridge-fall: provisionera schema eller databas och kör baslinjemigreringar. Automatisera detta – manuell provisionering skalar inte.
  • Seeda standarddata (roller, inställningar) i en transaktion så att en halvfärdig tenant aldrig blir synlig.
  • Verifiera isolering i ett automatiserat test direkt efter provisionering: försök läsa en annan tenants data och bekräfta att det blockeras.

Zero-trust-tänket gäller även internt: anta aldrig att applikationslagret filtrerar rätt. Låt databasen vara den sista, oeftergivliga gränsen.

Vanliga misstag att undvika

  • Skjuta upp tenant_id "tills vi behöver det" – då är det redan för sent och dyrt.
  • Lita på enbart applikationsfiltrering utan RLS som skyddsnät.
  • Lägga auktoriseringsdata i fält som slutanvändaren kan ändra.
  • Hoppa över migreringsstrategi för silo – tusen scheman som ska migreras samtidigt blir en fredag du inte vill ha.
  • Ingen per-tenant-observability – då upptäcker du noisy neighbors först när kunderna hör av sig.

Vad det här betyder för din produkt

Rätt multitenancy-modell beror på din målgrupp, dina compliance-krav, förväntad tenant-volym och hur stor variation det är mellan kundernas laster. Det finns inget universellt svar – men det finns rätt och fel sätt att hålla dörren öppen för framtida val. På ZORC bygger vi SaaS-arkitekturer som börjar enkelt och poolat men som är förberedda för silo och bridge den dag enterprise-kunderna knackar på. Vill du ha en arkitektur som håller från MVP till skala? Hör av dig via kontakt eller gör en snabb behovsanalys i offertkalkylatorn.