Spring til indhold

Multi-tenant

Multi-tenant arkitektur og data-isolation

Vi designer multi-tenant-arkitektur i Postgres med Row-Level Security eller schema-isolation. Bygget så data er adskilt, performance holder og I kan migrere én tenant uden at røre alle andre.

3D-illustration af et enkelt gennemsigtigt glas-tårn med flere indre etager adskilt af glødende orange dividere — symbolet på streng tenant-isolation i én database.

Multi-tenancy designet rigtigt fra start

Det her bygger vi ikke om senere

Postgres Row-Level Security som default
RLS
Pr-tenant-isolation hvor det kræves
Schema
Provisioning, suspension, sletning som API
Lifecycle
SSO pr. tenant via WorkOS eller Clerk
SAML

Sådan vi tænker multi-tenancy

Den slags I kun bygger forkert én gang.

Multi-tenancy er den slags arkitektur-beslutning I kun bygger forkert én gang — fordi at lave det om senere typisk kræver at I rører hvert eneste API, hver eneste query og hvert eneste filsystem-kald i hele kodebasen. Vi designer multi-tenancy korrekt fra start, ud fra hvor mange tenants I forventer, hvilken isolations-grad jeres kunder kræver, og hvad der koster mindst at vedligeholde over de næste fem år.

Vores default for de fleste B2B SaaS er Postgres med Row-Level Security (RLS): én database, én skema, men hver række er taggset med en tenant_id og databasen håndhæver at queries kun ser deres egen tenants data. Det skalerer fra 10 til titusindvis af tenants på samme database, har den letteste drift, og fejler sikkert hvis applikationen glemmer at filtrere. Vi har også sat schema-isolation op (én skema pr. tenant) når enterprise-kunder kræver fysisk adskillelse, og dedikerede databases når det er reguleringskrav.

Lige så vigtigt som dataadskillelsen er hele organisations-modellen ovenpå: kan en bruger være i flere tenants? Kan en tenant invitere brugere via SAML? Hvordan håndteres roller pr. tenant? Vi designer det med jer fra dag ét — fordi det styrer både databasen, auth-laget og hele jeres administrations-UI.

Hvad I får leveret

Data-isolation, lifecycle og SSO bygget korrekt fra start.

Postgres RLS som default, schema-isolation hvor det kræves, SAML SSO pr. tenant.

  • Postgres RLS som standard

    Hver tabel får en tenant_id-kolonne og en RLS-policy der filtrerer pr. session-variable. Selv hvis applikationen glemmer at filtrere i en query, returnerer databasen kun den aktuelle tenants data. Sikkerhed som default, ikke som disciplin.

  • Schema-isolation når det skal til

    Til kunder der kræver fysisk adskillelse (typisk større enterprise eller regulerede brancher) bruger vi pr-tenant-skemaer i samme database. Migrationer rulles ud koordineret; pooler-konfigurationen håndterer skema-skift.

  • Tenant-livscyklus: provisionering, suspension, sletning

    Oprettelse af ny tenant er en API-handling — ikke en manuel proces. Suspension (fryser adgang men beholder data), genaktivering og sletning (med en grace-periode + verificerbar dataeksport) er bygget ind fra start.

  • Organisationer, brugere og roller

    Brugere kan tilhøre flere tenants og skifte mellem dem uden re-login. Roller defineres pr. tenant (admin, member, billing, custom) med veldefinerede permissions. Audit-log på følsomme handlinger pr. tenant.

  • Forbrug, kvoter og pr-tenant metrics

    Forbrug måles pr. tenant (API-kald, lager, brugere, features) så I kan både fakturere efter forbrug og forhindre at én tenant trækker ressourcerne fra alle andre. Rate-limiting og kvoter håndhæves på API-laget.

  • Migrations-strategi der ikke vælter

    Schema-ændringer rulles ud trinvist med backwards-compatible steps. Backfill kører som baggrundsjobs der respekterer tenant-grænser. Vi kan rulle ændringer ud til 1 tenant, så 10, så alle — uden big-bang-deploys.

Inden I forpligter jer

Det her bør I overveje først.

  • RLS, schema-isolation eller dedikeret database?

    RLS er default for de fleste B2B SaaS — letteste drift og bedst skala. Schema-isolation når enterprise-kunder kræver det; dedikerede databases når det er compliance-krav. De fleste SaaS slutter med en blanding: RLS for de fleste tenants, dedikerede setups for de største kunder. Vi designer det fra start så I kan have begge dele i samme produkt.

  • Cross-tenant features (admin, support)

    Internt har I brug for at se data på tværs af tenants — support skal kunne hjælpe en kunde, økonomi skal kunne se forbrug. Det skal designes ind fra start: en separat 'super-admin'-rolle der eksplicit kan se på tværs, med audit-log på hver kryds-tenant-handling. Ikke en bagvej; en eksplicit mekanisme.

  • Performance når én tenant fylder mere end andre

    I en RLS-database kan én tenants tunge queries trække performance ned for alle andre. Vi designer query-budgetter, statement-timeouts, og — for de største tenants — connection-pools dedikeret pr. tenant. Hvis én kunde vokser massivt, kan vi flytte dem til dedikeret infrastruktur uden at røre kodebasen.

  • GDPR: ret til sletning og dataeksport

    Når en tenant lukker sin konto, skal I kunne slette deres data verificerbart — ikke 'sat til arkiveret'. Vi designer dataejerskabet pr. tenant fra start så sletning er en operationel handling, ikke et månedslang oprydningsprojekt. Eksport leveres som JSON + assets så kunden kan migrere data ud.

FAQ

Det folk plejer at spørge om.

  • Hvor lang tid tager det at sætte multi-tenancy op?

    Hvis I bygger fra bunden, er det indlejret i den samlede SaaS-MVP og koster typisk 1–2 uger ekstra i fundamentsfasen. Hvis I retro-fitter multi-tenancy på en eksisterende single-tenant kodebase, snakker vi typisk 6–12 uger afhængigt af kodebasens størrelse — og det er en investering der kun er værd hvis I planlægger flere kunder, ellers bør I overveje dedikerede instanser i stedet.

  • Skal alle tabeller bruge RLS?

    Ja, som hovedregel. Alle tabeller med tenant-ejede data får en tenant_id-kolonne og en RLS-policy. Globale tabeller (configuration, system-data, plan-definitions) har ikke RLS — men de markeres eksplicit som global så ingen fejlbruger dem til tenant-data. Det skal være tydeligt hvilke tabeller hører hvor.

  • Hvordan tester vi at isolation faktisk virker?

    Vi skriver tests der bevidst forsøger at læse en anden tenants data — og fejler hvis det lykkes. De tests kører i CI ved hver pull request. Plus en periodisk audit hvor vi kører queries med session-variablen sat til en anden tenant og verificerer at intet returneres. Sikkerhed der kun testes i hovedet er ikke testet.

  • Kan vi have nogle tenants på dedikerede databases?

    Ja — det er ofte den rigtige model på sigt. Vi designer fra start med en tenant-routing-tabel der mapper tenant_id til en database-connection-streng. De fleste tenants peger på den fælles RLS-database; specifikke tenants kan pege på en dedikeret instans. Applikationen behøver ikke at vide hvilken model en tenant bruger.

  • Hvad med Single Sign-On pr. tenant?

    Vi sætter SAML SSO op pr. tenant via WorkOS, Clerk Enterprise eller Auth.js — så enterprise-kunder kan bruge deres egen IdP (Okta, Entra, Google Workspace) til at logge på deres tenant. Just-in-time-provisionering opretter brugere automatisk; SCIM trækker dem ud når de forlader IdP'en.

Klar til at starte?

Lad os tage en uforpligtende snak.

Vi vender tilbage indenfor en arbejdsdag med konkret input — ikke et standardtilbud.