Multi-tenant vs single-tenant | Valg af den rigtige SaaS-arkitektur
En teknisk sammenligning af multi-tenant og single-tenant SaaS-arkitekturer. Lær kompromiserne, og hvordan du vælger den rigtige tilgang til dit produkt.
Ethvert SaaS-produkt skal besvare et fundamentalt spørgsmål: hvordan betjener du flere kunder fra den samme software? Svaret er din tenancy-model. Den påvirker omkostninger, sikkerhed, ydeevne og hvor hurtigt du kan levere. At få det rigtigt tidligt sparer dig for smertefulde migreringer senere.
Definitioner
Multi-tenant
Én instans af applikationen betjener alle kunder. Alle deler de samme servere, den samme kodebase og ofte den samme database. Hver kundes data er logisk isoleret, men infrastrukturen er delt.
Tænk på det som en etageejendom. Alle lejere bor i den samme bygning, deler elevatoren og gangene, men har deres egen låste lejlighed med deres egne møbler.
Single-tenant
Hver kunde får sin egen dedikerede instans af applikationen. Separate servere, separate databaser, til tider separate kodebaser. Intet deles mellem kunder.
Tænk på det som fritliggende huse. Hver lejer har sin egen bygning, sine egne rør, sin egen have. Fuldstændig isolation, men dyrere at vedligeholde.
Sådan fungerer multi-tenancy
Der er tre almindelige tilgange til multi-tenant-arkitektur, hver med forskellige kompromiser.
Model 1: Delt applikation, delt database
Alle lejere deler en enkelt applikationsinstans og en enkelt database. Lejerdata adskilles ved hjælp af en lejeridentifikator (normalt en tenant_id-kolonne) på hver tabel.
Arkitektur:
- Én applikationsserver (eller cluster) håndterer alle forespørgsler.
- Én database gemmer alle lejerdata.
- Hver forespørgsel inkluderer en
WHERE tenant_id = ?-klausul for at afgrænse data til den korrekte lejer.
Fordele:
- Laveste infrastrukturomkostning. Én database, én app-deployment.
- Enklest at deploye og opdatere. Push én gang, alle får ændringen.
- Let at aggregere data på tværs af lejere til analyse og rapportering.
Ulemper:
- Højeste risiko for datalækage, hvis en forespørgsel glemmer lejerfiltret.
- Én støjende lejer kan forringe ydeevnen for alle andre.
- Database-migreringer påvirker alle lejere samtidig.
- Sværest at overholde dataresidens-regler.
Det er den mest almindelige tilgang for B2B SaaS-produkter med et stort antal små til mellemstore kunder.
Model 2: Delt applikation, separate databaser
Alle lejere deler den samme applikationsinstans, men hver lejer får sin egen database. Applikationen dirigerer forespørgsler til den korrekte database baseret på den autentificerede lejer.
Arkitektur:
- Én applikationsserver (eller cluster) håndterer alle forespørgsler.
- En separat database til hver lejer.
- Et routing-lag mapper lejeridentitet til den korrekte databaseforbindelse.
Fordele:
- Stærkere dataisolation. Ingen risiko for forespørgsler på tværs af lejere.
- Lettere at opfylde dataresidens-krav. Du kan placere hver database i lejerens påkrævede region.
- Backup og gendannelse pr. lejer er ligetil.
- Én lejers tunge forbrug låser ikke tabeller for andre lejere.
Ulemper:
- Mere infrastruktur at administrere. Hundredvis af lejere betyder hundredvis af databaser.
- Skemamigreringer skal anvendes på hver database individuelt.
- Rapportering på tværs af lejere kræver forespørgsler til flere databaser.
- Højere omkostning end en fuldt delt model.
Det er en stærk mellemvej for produkter, der har brug for bedre isolation uden omkostningen ved fuld single-tenancy.
Model 3: Separat applikation, separat database
Hver lejer får sin egen applikationsinstans og sin egen database. Fuldt isoleret. Det er i bund og grund single-tenancy, men administreret af SaaS-udbyderen i stedet for kunden.
Arkitektur:
- En dedikeret applikationsdeployment pr. lejer.
- En dedikeret database pr. lejer.
- Et routing-lag (ofte en load balancer eller API gateway) dirigerer trafik til den korrekte instans.
Fordele:
- Fuldstændig isolation. Ingen delte ressourcer mellem lejere.
- Maksimal fleksibilitet til tilpasning pr. lejer.
- Ydeevnen hos én lejer påvirker aldrig en anden.
- Simpleste compliance-historie.
Ulemper:
- Højeste infrastrukturomkostning langt.
- Deploymentkompleksitet vokser lineært med lejerantallet.
- Opdateringer skal rulles ud til hver instans individuelt (eller automatiseres meget omhyggeligt).
- Skalerer ikke økonomisk for store antal af små lejere.
Denne model giver mening for enterprise SaaS, hvor kunder kræver dedikeret infrastruktur og er villige til at betale en præmie for det.
Fordele og ulemper på et øjekast
| Faktor | Multi-tenant (delt DB) | Multi-tenant (separat DB) | Single-tenant |
|---|---|---|---|
| Infrastrukturomkostning | Lavest | Medium | Højest |
| Dataisolation | Logisk (rækkeniveau) | Fysisk (databaseniveau) | Fuldstændig |
| Deploymentkompleksitet | Lav | Medium | Høj |
| Opdateringshastighed | Øjeblikkelig for alle | Øjeblikkelig app, pr. DB-migreringer | Pr. instans-udrulning |
| Tilpasning | Begrænset | Begrænset | Fuld |
| Compliance | Sværere | Moderat | Nemmest |
| Skalerbarhed (lejerantal) | Fremragende | God | Dårlig |
| Støjende nabo-risiko | Høj | Medium | Ingen |
Dataisolation og sikkerhed
Dataisolation er den vigtigste overvejelse i enhver tenancy-model. Et sikkerhedsbrud, hvor én lejer kan tilgå en anden lejers data, er katastrofalt for en SaaS-virksomhed. Det kan ødelægge tillid, krænke regulativer og lukke virksomheden.
Row-level security
I en delt database-model er PostgreSQL’s Row-Level Security (RLS) et af de stærkeste forsvar mod datalækage. RLS håndhæver lejerisolation på databaseniveau, ikke applikationsniveau. Selv hvis din applikationskode har en fejl, der glemmer at filtrere efter lejer, forhindrer databasen selv adgang på tværs af lejere.
Sådan sætter du det op:
-- Enable RLS on a table
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
-- Create a policy that restricts access to the current tenant
CREATE POLICY tenant_isolation ON projects
USING (tenant_id = current_setting('app.current_tenant_id')::uuid);
-- Force RLS even for table owners
ALTER TABLE projects FORCE ROW LEVEL SECURITY;
Inden du eksekverer en forespørgsel, sæt lejerkonteksten:
-- Set at the beginning of each request/transaction
SET LOCAL app.current_tenant_id = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
-- Now this query automatically returns only the current tenant's data
SELECT * FROM projects;
-- No WHERE clause needed. RLS handles it.
Applikationsniveau-isolation
Ud over sikkerhed på databaseniveau bør din applikation håndhæve lejergrænser:
// Middleware that sets tenant context on every request
async function tenantMiddleware(req: Request, res: Response, next: NextFunction) {
const tenantId = extractTenantId(req); // From JWT, subdomain, or header
if (!tenantId) {
return res.status(401).json({ error: "Tenant not identified" });
}
// Set tenant context for the database connection
await db.raw(`SET LOCAL app.current_tenant_id = '${tenantId}'`);
req.tenantId = tenantId;
next();
}
Forsvar i dybden er princippet her. Stol aldrig på et enkelt lag af isolation. Kombiner filtrering på applikationsniveau, sikkerhed på databaseniveau og regelmæssige sikkerhedsrevisioner.
Ydeevneovervejelser
Udfordringer med delt database
I en delt database konkurrerer alle lejere om de samme ressourcer. En lejer, der kører en tung rapport, kan bremse forespørgsler for alle andre. Mitigeringer inkluderer:
- Connection pooling. Brug PgBouncer eller et lignende værktøj for at forhindre én lejer i at opbruge databaseforbindelser.
- Forespørgselstimeouts. Sæt maksimale eksekveringstider, så en løbsk forespørgsel ikke kan låse ressourcer på ubestemt tid.
- Ratebegrænsning. Håndhæv pr. lejer-grænser på API-forespørgsler og databaseoperationer.
- Read replicas. Diriger tunge læseoperationer (rapporter, eksporter) til en replika, så de ikke påvirker den primære database.
Fordele ved separate databaser
Med pr. lejer-databaser er ydeevneisolation indbygget. Én lejers tunge workload påvirker kun deres egen database. Du kan også provisionere større eller mindre databaser baseret på hver lejers plan og forbrug.
Kompromisset er administrationsoverhead. At overvåge 500 databaser er sværere end at overvåge én. Automatiseret tooling bliver essentielt.
Omkostningsimplikationer i skala
Lad os se på nogle grove tal. Antag at du har 100 lejere.
Delt database (multi-tenant):
- 1 applikationscluster: ~€200/måned
- 1 managed PostgreSQL-instans: ~€100/måned
- Total: ~€300/måned (€3 pr. lejer)
Separate databaser (multi-tenant):
- 1 applikationscluster: ~€200/måned
- 100 små databaseinstanser: ~€2.000/måned
- Total: ~€2.200/måned (€22 pr. lejer)
Single-tenant:
- 100 applikationsinstanser: ~€5.000/måned
- 100 databaseinstanser: ~€2.000/måned
- Total: ~€7.000/måned (€70 pr. lejer)
Disse tal er forenklede, men mønsteret holder. Delt infrastruktur er dramatisk billigere. Ved 1.000 lejere bliver gabet endnu bredere.
Derfor skal prissætning stemme overens med arkitekturen. Hvis du opkræver €20 pr. måned og kører single-tenant-infrastruktur til €70 pr. lejer, taber du penge på hver kunde.
Hvornår du vælger multi-tenant
Multi-tenant-arkitektur er det rigtige valg, når:
- Du bygger B2B SaaS til SMV’er. Høj volumen, lavere prispunkter og standardfunktionssæt.
- Omkostningseffektivitet er vigtig. Du skal holde infrastrukturomkostninger lave i forhold til omsætningen.
- Du ønsker hurtige, ensartede opdateringer. Deploy én gang, alle lejere får forbedringen.
- Dine kunder kræver ikke dedikeret infrastruktur. De fleste små og mellemstore virksomheder er ligeglade med, hvor deres data bor, så længe de er sikre.
- Du er i de tidlige stadier. Start multi-tenant. Det er billigere og enklere. Du kan altid tilbyde single-tenant senere til enterprise-kunder.
Hvornår du vælger single-tenant
Single-tenant-arkitektur giver mening, når:
- Du sælger til enterprises. Store organisationer kræver ofte dedikeret infrastruktur som en del af deres indkøbsproces.
- Compliance kræver det. Brancher som sundhed (HIPAA), finans (SOX, PCI-DSS) og offentlig sektor har strenge krav til dataisolation.
- Kunder har brug for tilpasning. Hvis hver kunde kræver forskellige konfigurationer, integrationer eller endda funktioner, giver single-tenant dig fleksibiliteten.
- Dit prispunkt understøtter det. Hvis du opkræver €5.000 eller mere pr. måned pr. kunde, er infrastrukturomkostningen let retfærdiggjort.
- Dataresidens er et hårdt krav. Når data skal ligge i et bestemt land, er separat infrastruktur pr. lejer den mest ligetil tilgang.
Hybridtilgange
Du behøver ikke vælge kun én. Mange succesfulde SaaS-virksomheder bruger en hybridmodel:
- Multi-tenant til standardniveauer. Gratis, starter og pro-kunder deler infrastruktur. Det holder omkostningerne lave og lader dig skalere.
- Single-tenant til enterprise. Premium-kunder får dedikerede instanser med brugerdefinerede SLA’er, compliance-certificeringer og dedikeret support.
Applikationskoden er den samme. Deploymentmodellen er forskellig. Det kræver god infrastrukturautomatisering, men det er et bevist mønster.
Sådan implementerer du en hybridmodel
- Byg appen som multi-tenant først. Al lejerisolationslogikken forbliver den samme uanset deploymentmodel.
- Brug infrastructure-as-code (Terraform, Pulumi eller CDK) til at automatisere miljøoprettelse.
- Opret en provisioneringspipeline, der kan spinne et nyt dedikeret miljø op på minutter, ikke dage.
- Vedligehold en enkelt kodebase. Det samme Docker-image kører i både delte og dedikerede miljøer. Konfiguration (ikke kode) bestemmer adfærden.
Databasestrategier i detaljer
Databasen er der, hvor tenancy-beslutninger har størst effekt. Her er tre gennemprøvede strategier.
Strategi 1: Delte tabeller med tenant_id
Hver tabel har en tenant_id-kolonne. Alle forespørgsler filtrerer efter den.
CREATE TABLE projects (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES tenants(id),
name TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX idx_projects_tenant ON projects(tenant_id);
-- Always query with tenant context
SELECT * FROM projects WHERE tenant_id = $1;
Bedst til: De fleste SaaS-produkter. Simpelt, omkostningseffektivt, velforstået.
Strategi 2: Skema pr. lejer
Hver lejer får sit eget PostgreSQL-skema inden for en delt database. Tabeller har samme struktur, men data er fysisk adskilt.
-- Create a schema for a new tenant
CREATE SCHEMA tenant_abc123;
-- Create tables in the tenant's schema
CREATE TABLE tenant_abc123.projects (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT now()
);
-- Set the search path per request
SET search_path TO tenant_abc123, public;
-- Now queries are automatically scoped
SELECT * FROM projects;
Bedst til: Produkter, der har brug for stærkere isolation end rækkeniveau, men ikke vil have omkostningen ved separate databaser. Fungerer godt op til et par hundrede lejere.
Strategi 3: Separate databaser
Hver lejer får en dedikeret PostgreSQL-instans (eller en dedikeret database på en delt server).
// Database connection routing
class TenantDatabaseRouter {
private connections: Map<string, DatabasePool> = new Map();
async getConnection(tenantId: string): Promise<DatabasePool> {
if (this.connections.has(tenantId)) {
return this.connections.get(tenantId)!;
}
const config = await this.loadTenantDbConfig(tenantId);
const pool = new DatabasePool({
host: config.host,
port: config.port,
database: config.database,
user: config.user,
password: config.password,
});
this.connections.set(tenantId, pool);
return pool;
}
private async loadTenantDbConfig(tenantId: string): Promise<DbConfig> {
// Look up tenant's database connection details
// from a central configuration store
return await configStore.get(`tenants/${tenantId}/database`);
}
}
Bedst til: Enterprise SaaS med højværdi-kunder, strenge compliance-krav eller dataresidens-forpligtelser.
At træffe beslutningen
Her er et simpelt beslutningsframework:
- Hvad er din målkundestørrelse? SMV peger mod multi-tenant. Enterprise peger mod single-tenant eller hybrid.
- Hvad er dit prispunkt? Under €100/måned har du brug for multi-tenant for at være profitabel. Over €1.000/måned bliver single-tenant levedygtigt.
- Hvad er compliance-kravene? Regulerede brancher kræver ofte stærkere isolation.
- Hvor mange lejere forventer du? Hundredvis eller tusindvis af lejere har brug for delt infrastruktur. Ti til halvtreds store lejere kan fungere med dedikerede instanser.
- Hvad er dit teams operationelle kapacitet? Single-tenant kræver mere DevOps-investering. Multi-tenant er operationelt enklere.
Hvis du er i tvivl, start med multi-tenant med en delt database og row-level security. Det er den laveste omkostningsmulighed, den er sikker, når den er implementeret korrekt, og den holder din arkitektur enkel. Du kan altid tilføje et dedikeret niveau til enterprise-kunder senere.
Bundlinjen
Der er ingen universelt korrekt tenancy-model. Det rigtige valg afhænger af dine kunder, din prissætning, dine compliance-krav og dine operationelle kapabiliteter.
De fleste SaaS-produkter bør starte multi-tenant. Det er billigere, enklere og skalerer godt. Efterhånden som du bevæger dig opmarket og begynder at sælge til større organisationer, tilføj single-tenant-muligheder til kunder, der har brug for dem og vil betale derefter.
Arkitekturen bør tjene forretningen, ikke omvendt. Byg til de kunder, du har i dag, og design med nok fleksibilitet til at betjene de kunder, du ønsker i morgen.
Har du brug for hjælp til at vælge den rigtige arkitektur til dit SaaS-produkt? Vi har bygget multi-tenant og single-tenant systemer på tværs af brancher. Lad os finde den bedste tilgang til dit projekt.