Serverless

Concept

An approach where you deploy code as individual functions and they run only when a request arrives, instead of renting and managing a server.

Why it exists

A server stays switched on during the hours when no requests arrive, and it costs the same money during those hours. Keep one running around the clock for an export feature called 200 times a day and the code actually executes for about six minutes a day. The other 23 hours and 54 minutes bill identically while doing nothing. Idle time is the whole of what this model refuses to pay for.

Capacity planning compounded the waste. You have to provision for the busiest moment, so the machine gets sized against nine on Monday morning, and most of that headroom idles the rest of the week.

Keeping it running also carried its own work. Apply operating system patches, clear the disk before it fills, restart the process when it dies overnight. None of it builds a feature, and somebody has to do all of it — quietly consuming one person's time without producing anything new. That work also never appears on a roadmap.

So the unit of execution dropped from a program to a function, with nothing switched on during the silence. The servers didn't disappear; responsibility for thinking about them moved from you to somebody else.

How it works

One function is the deployment unit, and an event wakes it.

  1. Code is deployed per function. The code handling one request, the code converting a file after it's uploaded, and the code aggregating at three in the morning each deploy separately.
  2. The execution environment is created on demand and disappears after a stretch with no calls. So the first request after a quiet period waits for an environment to be prepared. That delay is a cold start, and depending on the language and how much has to be loaded it runs from a few hundred milliseconds to several seconds. Which means the worst latency any user sees is the one right after the quietest hour of the day.
  3. Billing attaches to invocation count and execution time, with time multiplied by the memory allocated. A feature that runs six minutes a day is billed for six minutes. Memory is the knob that moves both cost and speed, and raising it sometimes lowers the bill.
  4. Concurrency scales on its own. Five hundred simultaneous requests bring up five hundred instances. This is where trouble usually starts: if the database behind them can't take 500 connections, everything the front end gained turns into a block at the back. Setting concurrency limits by hand is half the practical work — cap it at 50 and the rest queue, and that queue shows up as response time. A front end that scales freely helps only if everything behind it scales too.
  5. State can't be held. Nothing persists between invocations, and temporary files vanish with the environment. Everything worth remembering lives in storage outside. Anything cached in memory is gone by the next call, which catches out people porting existing code.
  6. There's an execution time ceiling, usually a few minutes. A 40-second export fits; a 40-minute aggregation has to be split or moved elsewhere. Splitting a long job means the pieces need somewhere to hand off, which usually means a queue.

The small deployment unit becomes a burden later. At eighty functions, which event wakes which code stops being visible from reading the code. Teams keep a separate inventory of the call relationships, or group related functions into one managed bundle.

Where it shows up

Four places where this approach earns its keep.

  1. Intermittent, event-driven work. Generating a preview after an upload, receiving notifications another service sends, aggregating at a set hour. What these share is that no user is sitting in front of a screen waiting for the result.
  2. Work with sharp traffic spikes. When fifty times the usual volume arrives for ten minutes after a marketing email goes out, you let it scale instead of provisioning for those ten minutes. Nothing has to be predicted, which is the part that saves the most work.
  3. Short code joining two services. Receiving a signal from a payment provider and reshaping it into your own format isn't worth a dedicated machine.
  4. Trying a new feature. With no server to prepare, you can attach something in a day, watch the reaction, and remove it.

Where it doesn't fit is equally clear. A feature that's latency-sensitive and takes steady requests all day is cheaper and faster left running. A steady load is precisely the case a running server was designed for. Jobs lasting tens of minutes, and architectures with tight limits on database connections, also fight this model.

Few teams build everything this way. Most keep one monolith at the center and peel off only the event-driven periphery as functions. The dividing line differs from microservices: what separates the pieces is execution frequency and events rather than features.

How it sounds at work

"This runs 200 times a day. There's no reason to keep a server up for it."

Choosing the execution model from the call frequency.

"Five hundred functions came up and the database can't take it. Cap the concurrency."

Scaling only the front end creates a block behind it.

"First call takes three seconds. We can't use this on that screen."

The cold start is visible to the user here.

Pagedeck moved document export to this model. Theo looked at the invocation log: 200 a day, concentrated on weekday mornings. A feature that had been costing $60 a month on a dedicated machine came to $3 a month as a function.

A proposal to do the same for document viewing came up and was dropped. Viewing arrives without pause all day and sits directly in front of how fast a screen appears, and the arithmetic came out more expensive too. Both features were about the same size in code. The difference wasn't size but whether the calls arrive evenly.

What people get wrong

The most common reading is that there is no server. The name invites it. But the code still runs on somebody's server; what changed is that preparing and defending that server isn't your job. Read it as absence and you expect server problems to disappear, when constraints specific to this model — the execution ceiling, the concurrency limit — take their place. The list of constraints changed; the constraints didn't go away. Operations didn't vanish either — it turned into configuring limits and reading somebody else's dashboards.

The other frequent belief is that it's always cheaper. You pay nothing while idle, so it reads that way. But as invocations grow steadily, at some point keeping something running becomes cheaper. Two hundred calls a day favors functions and 200 calls a second favors a server, with a crossover somewhere in between. Before moving, calculate both bills from your current invocation count and execution time.

Where to go next

  • Software architecture

    see where this sits among the seven structures

  • Monolith

    see the central structure it usually works alongside, and what belongs where

Related terms

Last updated 2026-09-16