Sådan skalerer du en SaaS teknisk: fra 10 til 10.000 brugere
Sådan skalerer du en SaaS fra 10 til 10.000 brugere: måling, indekser, køer, caching og flere servere i den rigtige rækkefølge, og hvad der kan vente.

Freelance full-stack udvikler
- Udgivet
- Læsetid
- 13 min.
Indhold i indlægget8
Du skalerer en SaaS ved at finde og fjerne den flaskehals der gør ondt lige nu, i en fast rækkefølge: mål først, ret databasen, flyt tungt arbejde over i en kø, cache det der er dyrt at beregne, og tilføj først derefter flere servere. For de fleste B2B-produkter kan du efter min vurdering skalere en SaaS fra 10 til 10.000 brugere med én kodebase, én database og en kø, uden microservices eller Kubernetes.
Det dyreste du kan gøre, er at bygge til 10.000 brugere, før du har 10.
Den korte version
| Typisk flaskehals | Det du gør nu | Det kan vente | |
|---|---|---|---|
| 10-100 brugere | Sjældent teknisk. Det svære er at få kunder | Én server, administreret database, backup og fejllogning | Kø-servere, caching, flere servere |
| 100-1.000 brugere | Langsomme forespørgsler og manglende indekser | Mål svartider, tilføj indekser, ret N+1-forespørgsler, flyt e-mails og eksport i kø | Load balancer og læsekopier af databasen |
| 1.000-10.000 brugere | Tunge baggrundsjob og databasen | Cache dyre beregninger, større database, separat server til køen, sessions og filer væk fra serverens disk | Sharding og microservices |
| Over 10.000 brugere | Afhænger af produktet og de største kunder | Flere app-servere bag en load balancer, læsekopier af databasen, egne databaser til store kunder | Microservices, medmindre det er teamet og ikke trafikken der kræver det |
Brugertallene er vejledende. En SaaS hvor hver kunde importerer store filer hver nat, rammer loftet langt tidligere end et simpelt bookingværktøj med samme antal brugere. Brug tabellen som en rækkefølge, ikke som en tidsplan.
Det samlede forløb fra idé til betalende kunder gennemgår jeg i min guide til at bygge en SaaS.
Hvad 10.000 brugere egentlig betyder
10.000 oprettede brugere er ikke 10.000 mennesker der klikker på samme tid. I en typisk B2B-SaaS logger en del af brugerne ind hver dag, nogle en gang om ugen og resten sjældent. Det er belastningen pr. sekund i de travleste timer der afgør om systemet holder, ikke antallet af rækker i brugertabellen.
Et groft regnestykke viser hvorfor. Antag at 20 % af 10.000 brugere er aktive på en given dag, og at hver af dem sender 100 forespørgsler til serveren i løbet af en arbejdsdag på 8 timer. Det giver 200.000 forespørgsler fordelt på 28.800 sekunder, altså cirka 7 i sekundet i gennemsnit. Er spidsbelastningen fem gange højere, er du oppe på omkring 35 i sekundet.
Tallene er antagelser, ikke målinger, men størrelsesordenen er pointen: for mange B2B-produkter kan én velkonfigureret server bære det, så længe forespørgslerne mod databasen er effektive.
Det der oftere vælter et system, er de tunge handlinger. En kunde der eksporterer to års data. En import af 50.000 rækker fra et regneark. En rapport der regner på alt, eller en natlig kørsel der sender e-mails til samtlige brugere. Én stor kunde kan belaste systemet mere end hundrede små, og det er en af grundene til at din multi-tenant-arkitektur, altså måden flere kunder deler samme system på, betyder noget for skalering og ikke kun for sikkerhed.
Byg ikke til 10.000 brugere på dag 1
Microservices (systemet delt op i mange små tjenester), Kubernetes (et system til at drive mange servere og containere) og flere databaser føles ansvarligt, når man håber på succes. I praksis koster det mere at bygge og drive, og hver ændring tager længere tid.
Det sidste er det værste. I det første år skal en SaaS kunne ændre sig hurtigt, mens du finder ud af hvad kunderne faktisk vil betale for. Min vurdering er, at et nyt produkt langt oftere har for få brugere end for mange. Et skaleringsproblem er et problem du kan løse med tid og penge, når indtjeningen er der.
Det betyder ikke at du skal ignorere skalering. Det betyder at du vælger et velkendt fundament og lader være med at løse problemer du ikke har endnu. Hvad der hører til i første version, gennemgår jeg i indlægget om at afgrænse en SaaS-MVP, og hvilket fundament jeg typisk anbefaler, står i min gennemgang af tech stack til SaaS.
Tre ting der er billige nu og dyre senere
- Kunde-id og indekser fra start: hver tabel med kundedata skal have et kunde-id, og de indekser du søger på, bør starte med det. Det gør både adskillelse og hastighed enklere, når datamængden vokser.
- Tungt arbejde skrevet som baggrundsjob: e-mails, PDF'er og importer skrives som selvstændige job. I Laravel kan køen starte på "database"-driveren, som bruger den database du allerede har, så du behøver hverken Redis eller en separat kø-server fra start. Når du får brug for mere, er skiftet til Redis en ændring i konfigurationen og ikke i koden.
- En app der ikke husker noget på sin egen disk: sessions, cache og uploadede filer skal ligge i databasen, i Redis eller i et fillager som Amazon S3, ikke i en mappe på serveren. Så kan du senere starte en server nummer to, uden at brugerne bliver logget ud eller filer forsvinder.
Tegn på at det er tid til at skalere
Skalér når målingerne viser at noget er ved at give efter, ikke fordi brugertallet runder et rundt tal. Det er de tegn jeg holder øje med:
- Svartiden for de langsomste 5 % af forespørgslerne stiger uge for uge, selvom koden ikke er ændret.
- Køen hober sig op, så e-mails og eksport kommer minutter eller timer for sent i travle perioder.
- Databaseserveren kører med høj CPU eller løber tør for forbindelser i spidsbelastningen.
- Timeouts og fejl topper på bestemte tidspunkter, fx mandag morgen eller ved månedsskiftet.
- Kunderne begynder at sige at systemet "er blevet langsomt".
Det sidste punkt er det dyreste. Langsomme sider og fejl er en af de tekniske grunde til at kunder stille og roligt finder et alternativ, og det har jeg skrevet mere om i indlægget om tekniske årsager til at SaaS-kunder opsiger.
Trin for trin: skalering i den rigtige rækkefølge
Hvert trin herunder er billigere end det næste, og efter min vurdering løser de første tre langt de fleste skaleringsproblemer op til 10.000 brugere.
1. Mål før du ændrer noget
Saml svartider pr. side, de langsomste databaseforespørgsler, langsomme baggrundsjob og fejl ét sted. I Laravel er Laravel Pulse et godt første skridt: det viser blandt andet langsomme forespørgsler, langsomme job og køernes gennemløb, og det kræver ikke ekstra infrastruktur. Til nedbrud og fejl har du desuden brug for overvågning udefra, så du opdager problemet før kunderne.
Kig ikke kun på gennemsnittet. Et gennemsnit på 200 millisekunder kan skjule at hver tyvende side tager to sekunder.
2. Ret databasen: indekser og N+1-forespørgsler
Databasen er typisk det første sted flaskehalsen viser sig, og der er to klassiske fejl. Den første er manglende indekser. Uden et indeks må databasen læse hele tabellen for at finde de rækker den skal bruge. Det går fint med 1.000 rækker og dårligt med 10 millioner. Med kommandoen EXPLAIN kan du se hvordan databasen faktisk udfører en forespørgsel, og PostgreSQL's gennemgang af EXPLAIN forklarer hvordan du læser resultatet.
Den anden fejl er N+1-forespørgsler: en liste med 50 rækker der laver én forespørgsel til selve listen og derefter én ekstra pr. række. Fejlen skyldes lazy loading, hvor relaterede data hentes én række ad gangen. Laravel kan slå lazy loading fra under udvikling, så fejlen bliver fanget før den kommer i drift.
Ret de to ting, før du køber en større server. En større server gør en dårlig forespørgsel lidt hurtigere, men den er stadig dårlig. Flere almindelige årsager finder du i min gennemgang af hvorfor en webapp bliver langsom.
3. Flyt tungt arbejde over i en kø
Alt der ikke skal være færdigt, før brugeren ser næste side, hører hjemme i en kø: e-mails, PDF'er, importer, eksport, webhooks til andre systemer og kald til AI-tjenester. Brugeren får svar med det samme, og arbejdet udføres i baggrunden af separate processer. Laravels dokumentation om køer bruger netop indlæsning af en uploadet CSV-fil som eksempel på en opgave der tager for lang tid til en almindelig forespørgsel.
Tre ting skal være på plads. Et job skal kunne køre igen uden at gøre skade, hvis det fejler halvvejs: en fakturamail sendt to gange er pinlig, en betaling trukket to gange er værre. Fejlede job skal opdages og ikke bare forsvinde. Og én tung kunde må ikke kunne blokere køen for alle andre, så del arbejdet op i flere køer efter prioritet. Bruger du Redis som kø, giver Laravel Horizon et overblik over køerne og hvad der fejler.
4. Cache det der er dyrt og sjældent ændrer sig
Caching betyder at du gemmer resultatet af en dyr beregning, så den næste bruger får det med det samme. Gode kandidater er tal på et dashboard, opslag der bruges på hver side, og svar fra eksterne API'er der ikke ændrer sig hvert minut. Brug en delt cache som Redis, så alle servere ser det samme.
Caching har to faldgruber. Den første er at bruge cache til at skjule et manglende indeks, så du ender med to problemer i stedet for ét. Den anden er forældede data. Det svære er at vide hvornår noget skal smides ud af cachen. I en SaaS med mange kunder skal nøglerne desuden indeholde kunde-id, så kunde A aldrig ser kunde B's tal.
5. Skalér op, før du skalerer ud
At skalere op betyder en større server eller en større database. At skalere ud betyder flere servere side om side. Op er næsten altid det enkleste næste skridt: ingen kodeændringer og ingen nye fejlkilder, bare en større maskine. En administreret database hos en hostingudbyder giver dig samtidig backup, opdateringer og plads til at vokse, uden at du selv skal drive databaseserveren.
Flyt også kø-arbejdet over på sin egen server, når det begynder at konkurrere med brugernes forespørgsler om CPU, så en tung import ikke gør siderne langsomme. Det kræver at filerne ligger i et fælles fillager.
6. Flere servere bag en load balancer
Når én server ikke længere er nok, eller når du ikke vil have at hele systemet står stille hvis den ene server går ned, sætter du to eller flere app-servere bag en load balancer, som fordeler trafikken mellem dem. Her betaler de billige beslutninger fra dag 1 sig. Sessions, cache og filer ligger allerede et fælles sted, så det er ligegyldigt hvilken server brugeren rammer.
Pas på planlagte opgaver. Kører Laravels planlægger af faste opgaver (scheduleren) på tre servere, bliver ugens rapport genereret tre gange. Laravel løser det med onOneServer, som kræver at alle servere bruger den samme centrale cache.
7. Del databasen op til sidst
Databasen er den sværeste del at skalere ud, fordi data altid skal være korrekte. Det første skridt er læsekopier (read replicas): kopier af databasen der kun bruges til læsning, fx til rapporter og søgning. Det næste er at flytte enkelte meget store kunder over i deres egen database, og det er langt nemmere hvis kunde-id står på alle tabeller fra start.
Egentlig sharding, hvor data deles over mange databaser efter en nøgle, har efter min vurdering meget få SaaS-produkter brug for ved 10.000 brugere. Når du når dertil, har du som regel også råd til folk der arbejder med drift på fuld tid.
Hvornår du ikke skal gøre det alene
Planen ovenfor kan gennemføres af én erfaren udvikler med en god hostingudbyder i ryggen. Men der er situationer hvor det ikke er nok:
- Du har krav om oppetid døgnet rundt med vagtordning, fx fordi kunderne er hospitaler eller kritisk infrastruktur. Så skal flere personer kunne rykke ud om natten, og det kan én freelancer ikke love.
- Du forventer mange tusinde samtidige brugere fra første dag, fx fordi en stor partner lancerer produktet til alle sine kunder på én gang.
- Kunderne kræver certificeringer og revision af driften, hvilket forudsætter et team med dokumenterede processer.
I de tilfælde har du brug for et team med dedikeret drift eller en DevOps-specialist ved siden af udvikleren. Jeg siger det hellere nu end efter et halvt års samarbejde.
Har du derimod nogle hundrede eller få tusinde brugere, og er tingene begyndt at gå langsomt, er det en opgave hvor én udvikler med overblik over hele kodebasen kan komme hurtigt frem.
Næste skridt
Start med at måle. Mangler du tal på svartider, langsomme forespørgsler og køer, er det dit første skridt at skaffe dem, uanset hvor mange brugere du har. Brug tjeklisten til at se hvor du står i dag.
Er din SaaS klar til at vokse?
- Du måler svartider, langsomme forespørgsler og fejl, og du kan se de langsomste 5 % af forespørgslerne.
- Alle tabeller med kundedata har et kunde-id, og de vigtigste forespørgsler bruger et indeks.
- Lazy loading er slået fra under udvikling, så N+1-forespørgsler bliver fanget.
- E-mails, eksport, import og kald til eksterne tjenester kører i en kø, og fejlede job bliver opdaget.
- Sessions, cache og uploadede filer ligger uden for app-serverens egen disk.
- Planlagte opgaver kører kun på én server ad gangen.
- Databasen har automatisk backup, og du har prøvet at gendanne den.
- Du ved hvilke kunder og handlinger der belaster systemet mest.
Mangler flere af punkterne, ville jeg starte med en gennemgang af kodebasen og målingerne og en prioriteret plan, så de billigste forbedringer kommer først. Vil du se hvordan jeg arbejder med SaaS-produkter, fra et forprojekt til fast pris og frem til drift og videreudvikling, så læs om min udvikling af SaaS-produkter.
Ofte stillede spørgsmål
Kan Laravel skalere til mange brugere?
Ja. Frameworket er sjældent det der sætter grænsen ved 10.000 brugere. Flaskehalsen er næsten altid databasen, tunge baggrundsopgaver eller måden koden henter data på. Laravel har køer, cache, planlagte opgaver på én server og måleværktøjer indbygget eller som officielle pakker, så trinene i dette indlæg kræver ikke et skift af teknologi.
Har jeg brug for Kubernetes eller serverless?
Sjældent ved 10.000 brugere. Kubernetes er stærkt til mange tjenester og store teams, men kræver særlig viden at drive, og den tid går fra produktet. Serverless kan passe til meget ujævn trafik, men gør fejlsøgning mere besværlig og kan blive dyrt ved jævn belastning. Min anbefaling er en administreret hostingplatform eller almindelige servere, indtil du har en konkret grund til andet.
Hvordan load-tester jeg min SaaS før lancering?
Lav en kopi af produktionsmiljøet med realistiske mængder data, og send trafik mod de tunge sider med et værktøj som k6. Test de handlinger der faktisk belaster systemet, som login, søgning, rapporter og import, ikke kun forsiden. Øg trafikken gradvist. Kør ikke tests mod produktion, medmindre du er sikker på at de ikke rammer rigtige kunder.
Hvad koster det at skalere en SaaS til 10.000 brugere?
Det afhænger mest af hvor meget der skal rettes i koden, ikke af serverne. For mange B2B-produkter er hostingregningen ved 10.000 brugere en mindre post sammenlignet med udviklertiden. Den store udgift opstår når skalering skal bygges ind bagefter: manglende kunde-id, filer på serverens disk og tungt arbejde midt i brugernes forespørgsler. En gennemgang med målinger giver det mest præcise estimat.