Ugrás a tartalomhoz
← Vissza a blogra

Multi-tenant SaaS építés MVP-ből — 6 hiba, amit nem szabad elkövetni

Tenant_id mindenhol, RLS első naptól, sharding-halasztás 200 tenantig, per-tenant sequence, Host-header resolution, tenant-per-index. 6 buktató — javítás 18 hónap múlva nem opció.

Multi-tenant SaaS építés MVP-ből — 6 hiba, amit nem szabad elkövetni

Minden SaaS, amit elindítasz, előbb-utóbb multi-tenant lesz. A kérdés csak az, hogy te tervezed-e be, vagy a 7. ügyféled fogja kikényszeríteni egy late-night incidentben. Hat hiba, amit mi vagy az ügyfeleink elkövettünk, és amitől szeretnénk megóvni.

1. tenant_id elfelejtése egy táblán

Az alapszabály: MINDEN üzleti tábla első oszlopa tenant_id. Még a tags is. Még a user_preferences is. A legkisebb kivétel is megbosszulja magát — egy ügyfél nálunk 14 hónap múlva fedezte fel, hogy az email_templates táblán nincs tenant_id, és a B-tenant által mentett sablon megjelent az A-tenant fiókjában.

Kényszerítsd ki migration-szinten: ne legyen tábla tenant_id nélkül, kivéve nyíltan közöset (pl. tenants, tenant_billing_plans).

2. Row-level security (RLS) nélkül indulás

„Majd a service layer ellenőrzi.” Nem fogja. Egyetlen elfelejtett WHERE egy admin-eszközben, egyetlen rosszul scope-olt JOIN, és az adat keresztbe folyik. Postgres RLS bekapcsolása nem opcionális — az MVP első hetén megy be.

Mért adat egy 2026-os ügyfél-audithoz: 17 service-réteg lekérdezésből 3 nem szűrt tenant_id-ra. RLS-sel ezek hibára futnak, anélkül észrevétlenül szivárogtak volna.

3. Túl korai sharding

A „skálázni fogunk” narratíva ellenére: az első 200 tenantig egyetlen Postgres elég. A sharding-tax (cross-shard JOIN, eventual consistency, devops bonyolítás) most több költség, mint amennyi haszon. Tedd be a shard-key oszlopot (shard_key), tedd be a tenant→shard mapping táblát — de maradj egy shardon addig, amíg a p99 > 500ms vagy a DB-CPU > 70% nem tartós.

4. Közös sequence per tenant

A quote_number és társai: ha SERIAL-t használsz egyetlen sequence-szel, B-tenant ajánlatszámai ugranak A-tenant ajánlatszámai miatt. Ez nemcsak csúnya — könyvelési problémát is szül.

Minta: (tenant_id, sequence_id) kompozit, INSERT ... RETURNING egy per-tenant nextval('tenant_X_quotes_seq')-ből, vagy explicit tenant_counters tábla FOR UPDATE-tel. Egyszerű, és mindkét fél hálás.

5. Hard-coded subdomain

„Egyelőre acme.app.example.com alá tesszük az Acme-t.” Hat hónap múlva: 47 subdomain, Cloudflare DNS-szabály karbantarthatatlan, SSL-cert-rotation egy rémálom. Ráadásul az új ügyfél már a saját domainjén akarja látni a SaaS-t (portal.acme.com).

Kezdettől fogva: Host-header alapú tenant resolution. A subdomain csak egy kényelmi alias. Az adatbázisban a tenant „host_aliases” mező egy listát tárol (acme.com, portal.acme.com, acme.app.example.com). Egy ingress, egy wildcard cert, sok host.

6. Közös search index

Elasticsearch / Meilisearch / OpenSearch: ha az egész SaaS egyetlen indexre keres, a tenant_id filter csak query-time. A query-tervező drága lesz, a re-index egy tenantre az egész indexet érinti, és egy konfig-hiba megint adatszivárgáshoz vezethet. Tenant-per-index (vagy legalább per-index-alias) — kicsit drágább storage, sokkal egyszerűbb biztonság.

A tanulság

A multi-tenant nem egy „kapcsoló, amit később felcsapunk”. Architektúra-réteg, és az MVP első napján kell beletervezned. A fenti hat hiba mindegyike újraírást kíván a 18. hónapban — kivéve, ha az 1. hónapban már jól csináltad.

Beszéljünk a projektedről

Mondd el, mit építesz — meglátjuk, hogyan segíthetünk.