The idea: no server between calls

A classic web server is started once and keeps running. A serverless function such as AWS Lambda scales to zero: when no request comes, nothing runs and nothing is billed. The price is paid by the first request. Before its handler can run, the platform must build an execution environment for it. That wait is the cold start. Later requests reuse the environment and only run the handler: they are warm.

The life of one execution environment: INIT (create microVM 125 ms, download code 50 ms, start runtime 120 ms, init code 180 ms), then INVOKE (handler 50 ms), then frozen between calls; a warm call runs only the handler; after about 10 minutes idle the environment is reclaimed and the next call starts again from INIT.
The first call pays for INIT; warm calls pay only for the handler, until the environment is reclaimed.

What a cold start does

Lambda calls the first part the INIT phase and the handler the INVOKE phase. The page uses these numbers (rough, but in the right range):

stepwhat happensNode.js 22Java 21
create sandboxboot a Firecracker microVM on a worker host125 ms125 ms
download codefetch and unpack the zip (5 MB / 50 MB)50 / 250 ms50 / 250 ms
start runtimestart the language runtime120 ms450 ms
init codecode outside the handler: imports, SDK clients, DB connection, framework180 ms700 ms
handlerthe request itself50 ms50 ms
cold totalwith the 5 MB zip525 ms1375 ms

The first request in Demo: cold start, then warm takes 525 ms; the second takes 50 ms. Only the handler is your business logic; the rest is set-up.

Warm, frozen, reclaimed

After a response, Lambda freezes the environment: the process stays in memory but gets no CPU. The next request thaws it and runs only the handler. Global variables, open connections and files in /tmp survive, which is why init code is the place for clients and connection pools. A frozen environment is kept only for a while: AWS does not publish the time, and the page assumes about 10 minutes. After 5 idle minutes the call is still warm (Demo: idle 5 min, still warm); after 15 it is cold again (Demo: idle 15 min, cold again).

A burst: one cold start per request

An environment handles one request at a time. If three requests arrive together and only one environment is free, the other two get new environments, each with its own cold start. In Demo: a burst of 3 = 3 cold starts all three wait 525 ms; the next burst finds three warm environments and takes 50 ms each. A traffic spike after a quiet period is therefore the worst case: many users see the cold start at once.

The runtime and SnapStart

A JVM starts slower than Node.js, and Java frameworks do a lot at start-up (class loading, dependency injection). SnapStart runs INIT once when a version is published, takes a snapshot of the microVM's memory, and restores that snapshot on a cold start instead of starting the runtime and running init again. In Demo: Java vs SnapStart the cold start drops from 1375 ms to 425 ms; warm calls are 50 ms either way. Code that must be unique per environment (random seeds, connections) has to be refreshed after a restore.

Latency bars made of phase segments: Node.js cold 525 ms, Java cold 1375 ms, Java with SnapStart cold 425 ms, any warm call 50 ms.
The handler is the same 50 ms everywhere; the cold start is what differs.

Provisioned concurrency vs a long-running server

Provisioned concurrency asks Lambda to keep N environments initialized at all times. In Demo: provisioned concurrency two of the three burst requests are warm, the third spills over to an on-demand environment and is cold, and the 15 idle minutes cost 2 × 15 = 30 instance-minutes. A long-running server ran its init once at deploy and never stops, so no request ever waits for it, and one process can serve many requests at once with an event loop (Demo: long-running server). It is paid for every idle minute too.

Lambda, on demandprovisioned concurrencylong-running server
first request after idlecold startwarm (up to N at once)fast
burst above capacityone cold start per extra requestcold above Nqueues in the server, or a new instance must start
idle costnoneN environmentsthe whole instance
requests per instanceone at a timeone at a timemany at once

Other ways to shrink a cold start: a smaller package (try the 50 MB zip in Options), fewer dependencies, lazy initialization, a lighter runtime, and more memory, which also gives more CPU. See also Kubernetes autoscaling for pods that scale up, vertical vs horizontal scaling, containers vs VMs, JIT tiering for why a fresh JVM is slow, and connection pools.

What the page leaves out

The numbers are fixed examples; real cold starts vary with memory size, region, VPC networking and luck. The page leaves out Lambda extensions and their own init, the 10-second INIT limit, the concurrency limit and throttling (429), container image functions and their lazy-loaded layers, how the placement service picks a worker host, the pre-warming Lambda does on its own, and the cost per GB-second.

On the mind map

This page on the Servers & Event Loops mind map · 26 pages in 5 branches · open it to see the whole map and test yourself in recall mode.