Architectuur
Serverless of eigen servers: kosten, cold starts en lock-in
Serverless is voordelig bij laag of onregelmatig verkeer. Een eigen server wint bij constant verkeer, lange processen of veel rekenwerk.

Serverless is voordelig als je verkeer laag of onregelmatig is en je geen tijd in servers wilt steken. Een eigen server, of een VM met containers, wint zodra het verkeer constant is, processen lang draaien of je veel rekenwerk doet. Kijk dus eerst naar de vorm van je verkeer en pas daarna naar de technologie.
Twee kostencurves
Bij serverless betaal je per request en per rekentijd. AWS Lambda rekent af per request en per GB-seconde, gemeten vanaf het moment dat je code start tot hij klaar is. De gratis laag is een miljoen requests en 400.000 GB-seconden per maand. Cloudflare Workers en Vercel tellen anders: daar betaal je voor CPU-tijd, en de tijd waarin je code wacht op een database of API telt niet mee (bij Vercel loopt het geheugen in die tijd wel door). Het betaalde Workers-plan heeft een minimum van 5 dollar per maand per account.
Een server kost een vast bedrag per maand, of hij nu stilstaat of vol draait, dus de prijs per request daalt naarmate je hem beter benut.
Reken het daarom na met je eigen cijfers. Pak het aantal requests per maand, de gemiddelde duur en het geheugen per functie, en zet dat naast de kleinste server die je piek aankan. Bij een API die vooral wacht op Postgres of een LLM maakt het afrekenmodel veel uit: betaal je voor de wandkloktijd (Lambda) of alleen voor CPU-tijd (Workers, Vercel)?
Cold starts zie je in je p95 en p99
Een cold start is de vertraging als het platform een nieuwe instantie moet opstarten. In het gemiddelde zie je hem zelden, in je p95 en p99 wel. Voor een webhook of een nachtelijke job maakt dat weinig uit, voor een checkout of een zoekveld wel.
De oplossingen kosten geld. Bij Lambda houdt provisioned concurrency instanties warm, maar je betaalt voor die capaciteit zolang hij aanstaat. Bij Google Cloud Run doe je hetzelfde met minimum instances. Met request-based billing betaal je een lager tarief voor een instantie die wacht, met instance-based billing het volle tarief. In beide gevallen betaal je weer voor stilstand, terwijl je die met serverless juist kwijt wilde.
Lambda rekent de initialisatiecode buiten je handler mee als duur. Een zware opstart (veel imports, een grote SDK, verbindingen opzetten) zie je dus terug in de latency en op de rekening. Vercel dempt cold starts in Fluid compute met bytecode caching en door productiedeployments voor te verwarmen, en laat meerdere requests één instantie delen.
Zet daarom eerst de p99 per endpoint in een dashboard, voordat je betaalt voor warme capaciteit.
Lock-in zit in alles rond de functie
De functie zelf is meestal gewone code. De binding zit in de triggers, de eventformaten, de rechten (IAM bij AWS), de queues, de configuratie en de manier waarop je logs en traces verzamelt.
Ik raad aan om de handler dun te houden. Hij vertaalt het event naar een gewone functieaanroep, en de bedrijfslogica staat in modules die niets van het platform weten. Die modules draai je lokaal en in je tests zonder emulator. Verhuizen naar een container is dan vooral een nieuwe adapter schrijven.
Let ook op de harde grenzen. Een Lambda-functie draait maximaal 15 minuten en krijgt maximaal 10.240 MB geheugen. Op Vercel Pro is de grens standaard 300 en maximaal 800 seconden (langer kan alleen in een bèta). Lange imports, videoverwerking of verbindingen die lang open blijven, passen daar slecht in.
Wie het beheer doet
Serverless haalt veel werk weg: je patcht geen besturingssysteem en plant geen capaciteit. Er komt wel ander werk voor terug. Je hebt overzicht nodig over tientallen functies en je moet de concurrency-limieten kennen (bij Lambda is het standaardquotum 1.000 gelijktijdige executies per regio, nieuwe accounts krijgen eerst minder). Databaseverbindingen worden een probleem als honderden korte instanties elk een eigen verbinding openen. Dan heb je een connection pooler voor Postgres nodig.
Bij een eigen server regel je zelf de updates, TLS, monitoring, backups en het schalen. Met Docker Compose op één of twee VPS'en is dat voor een team van een paar developers goed te doen. Wanneer je meer nodig hebt, staat in heb je Kubernetes nodig.
Mijn vuistregels
- Weinig of onvoorspelbaar verkeer, korte requests en niemand voor beheer: serverless.
- Constant verkeer, lange processen, veel CPU of websockets: containers op servers.
- Gemengd: de API in een container dicht bij de database, en cronjobs, webhooks en eventverwerking als functies.
Bekijk de keuze opnieuw als je cloudrekening of je verkeer verandert. In cloudkosten onder controle staat hoe je die maandelijkse check doet. Specifiek voor Next.js op Vercel tegenover een eigen Docker-host schreef Bas Vercel of zelf hosten.
Waar ik begin
Bij een nieuw product stel ik eerst vier vragen. Hoe ziet het verkeer eruit over een dag en over een week? Hoe lang duurt de langste taak? Waar moet de data staan? En wie krijgt de melding als het misgaat? Met die antwoorden is de keuze meestal snel gemaakt. Met welke stacks en platforms we werken, staat op de pagina technologie.
Bronnen
Veelgestelde vragen
Is serverless goedkoper dan een eigen server?
Bij weinig of onregelmatig verkeer meestal wel, omdat je per request en per rekentijd betaalt. Bij constant verkeer of lange processen is een vaste server vaak goedkoper. Reken het na met je eigen aantallen requests, duur en geheugen.
Hoe voorkom je cold starts?
Je kunt instanties warm houden met provisioned concurrency bij AWS Lambda of met minimum instances bij Google Cloud Run. Daar betaal je ook voor als er geen verkeer is. Meet daarom eerst of cold starts je p95 of p99 echt raken.
Hoe lang mag een serverless functie draaien?
Een AWS Lambda-functie stopt na maximaal 15 minuten. Op Vercel is de standaard 300 seconden, en op Pro kun je dat verhogen tot 800. Langere taken horen in een queue met een worker.
Over de auteur

Aleksa
Tech lead, Belgrado
Aleksa is tech lead in Belgrado. Hij stuurt het developmentteam aan, bewaakt de architectuur en rapporteert aan Erik.
Meer van Aleksa





