What are Serverless Cold Starts?

Last updated: July 2026

A cold start is a latency penalty paid when a serverless platform must create and initialize a new environment before running your code. It is not a bug but a bill: scale-to-zero means idle environments are reclaimed so idle costs nothing — and the first request after the reclaiming pays the setup. Understanding the phases, the real numbers, and the mitigation ladder turns cold starts from a vague fear into a priced engineering decision.

Key takeaways

QuestionAnswer
The causeScale-to-zero: no idle cost ⇒ someone initializes on demand
The phasesAllocate → download code → boot runtime → run init code → handle
The numbers~100 ms–1 s+ typical; under 1% of steady traffic, most of sparse traffic
The forgotten triggerConcurrency scale-out — warmers can’t fix it
The ladderFree code fixes first; paid always-warm capacity last

The five phases, with the clock running

COLD START                                            typical cost
1  Allocate a sandbox (micro-VM / container)          ~50–100 ms
2  Download your deployment package                    50–500 ms  ← scales with bundle size
3  Boot the language runtime                           50–1,000 ms ← interpreter fast, VM slow
4  Run YOUR init code (imports, SDK clients, DB conns) 0 ms–seconds ← the biggest lever you own
5  Invoke the handler                                  the actual work

WARM START = step 5 only (+ ~1–10 ms thaw). The environment was frozen,
not destroyed — connections and caches outside the handler survive,
which is why init discipline pays rent on every later request.

The contrast worth measuring yourself — a function on an always-running backend, where the race never starts:

// JavaScript / Node.js — Back4app JS SDK
// Cloud Code runs on an always-on backend — no scale-from-zero cold start
const t0 = Date.now();
const avg = await Parse.Cloud.run('averageStars', { movie: 'Arrival' });
console.log(`Round trip: ${Date.now() - t0} ms`); // consistent p50 ≈ p99
// The FaaS mitigations (warmers, provisioned capacity, bundle diets)
// don't apply here: the process serving this call was already running.
Cold path versus warm path for a serverless invocationAn incoming request either finds a warm, initialized environment and goes straight to the handler, or finds none and must wait for instance allocation, code download, runtime boot, and initialization code before the handler runs. Idle reclamation and deploys empty the warm pool, and concurrency spikes above it trigger additional cold starts.

yes

no — idle-reclaimed,
just deployed, or
concurrency spike

+100 ms – seconds

Request

Warm environment
available?

Handler runs
+ ~1–10 ms

Allocate → download →
boot → init

Environment frozen,
kept for reuse (minutes)

An incoming request either finds a warm, initialized environment and goes straight to the handler, or finds none and must wait for instance allocation, code download, runtime boot, and initialization code before the handler runs. Idle reclamation and deploys empty the warm pool, and concurrency spikes above it trigger additional cold starts.

Cold vs. warm starts

Cold startWarm start
EnvironmentCreated and initialized nowReused, thawed
Added latency~100 ms to secondsSingle-digit ms
WhenFirst call, post-deploy, post-idle, scale-outSteady traffic within the warm pool
Init codeRunsSkipped — its results persist
Billing noteOn major platforms, the init phase is now billed like executionHandler time only

How long, and how often — honestly

Duration depends mostly on runtime and bundle: interpreted runtimes (JavaScript, Python) typically 200–400 ms; compiled (Go, Rust) under ~100–300 ms; VM-based (JVM, .NET) 500 ms to multiple seconds, with snapshot-restore features cutting the JVM figure dramatically; p99s run 2–3× the median, and bloated dependency trees have been measured multiplying startup several-fold regardless of language. Frequency is where most explainers tell only half the story. Steady production traffic sees cold starts on under one percent of invocations — reassuring, and real. But the math inverts for sparse traffic: Fowler’s arithmetic — a function invoked once an hour cold-starts essentially every time, and dev environments see cold rates of 30–90%. And the trigger everyone forgets: concurrency scale-out — when ten requests arrive and three environments are warm, seven cold-start simultaneously, in the middle of your traffic spike, which is precisely when it hurts.

The mitigation ladder, priced

In cost order, cheapest first. Free, code-level: shrink the deployment bundle and prune dependencies — the single biggest lever most teams haven’t pulled; import only the SDK submodules you use; lazy-load heavy modules used by rare code paths; open database connections in init scope so warm starts reuse them. Cheap, configuration: raise memory (CPU scales with it, materially for VM runtimes); enable snapshot-restore where the platform offers it. Fragile, folk-remedy: keep-warm pings — a scheduled request every few minutes keeps one environment warm and does nothing for scale-out; honest status: legacy hack. Paid, definitive: pre-provisioned capacity (“provisioned concurrency,” “minimum instances”) — N environments always initialized, cold starts eliminated up to N, at an always-on price that partially cancels pay-per-use. The irony deserves its sentence: the fix for serverless’s signature problem is buying back the server you were promised you didn’t have.

Isolates: how edge runtimes sidestep it

Edge platforms report near-zero cold starts by changing the architecture rather than warming it: instead of booting a container or micro-VM per tenant, they run thousands of V8 isolates — browser-tab-style sandboxes — inside one long-running process. Creating an isolate context costs single-digit milliseconds and megabytes, not hundreds of milliseconds and a runtime boot. The trade is the environment: a web-standard API subset, tight CPU caps, no filesystem — a different tool, not a free upgrade, covered honestly in the edge entry.

Common use cases where cold starts matter

  • Interactive APIs — a human is watching the spinner; p99 includes the cold tail.
  • Payments and checkout — latency-sensitive and conversion-priced.
  • Login and session issuance — the first impression path, often after idle periods.
  • Sparse-traffic endpoints — admin tools and internal APIs where nearly every call is cold.
  • Where they don’t: queued jobs, webhooks, scheduled work — async absorbs the tail invisibly.

Should you optimize cold starts? A decision matrix

SituationDo
Async/queued/scheduled workloadsNothing — cold starts are invisible here
Steady high traffic, interactiveCode-level fixes; measure before paying
Sparse traffic, user-facingMinimum instances on that path — or an always-on backend
VM runtime (JVM/.NET), latency-sensitiveSnapshot-restore + memory first
Spiky traffic with strict p99Provisioned capacity sized to the spike
Gateway-style logic, global usersIsolate-based edge runtimes
Most app backends on a BaaSAlready solved — no scale-from-zero exists

Limitations and trade-offs

  • Mitigations trade money for latency. Pre-warmed capacity is a standing bill; decide per-endpoint, not platform-wide.
  • Warmers lie to dashboards. A pinged function looks healthy while every real traffic spike still cold-starts the scale-out.
  • Init thrift has limits. Aggressive lazy-loading moves latency from cold starts into first-use paths — measure where you moved it.
  • Benchmarks age fast. Runtime rankings and platform numbers shift yearly; stale figures (and long-fixed networking penalties) still circulate — date your data.
  • The metric that matters is yours. Percentage-cold statistics describe someone else’s traffic; only your p99 under production-like load justifies spending.

Cold starts and Back4app

Back4app is an open-source Backend-as-a-Service (BaaS) platform that combines a managed database, auto-generated REST and GraphQL APIs, authentication, file storage, and Cloud Code serverless functions. The cold-start story here is architectural absence: Cloud Code runs inside an always-running backend, so there is no scale-from-zero moment — no init race, no warm pool to manage, no provisioned-capacity line item — and the code tabs’ measurement shows what that buys: p50 and p99 within shouting distance of each other, on the first request of the day and the millionth. The trade is the one named in BaaS vs. serverless: you give up per-invocation billing granularity for consistent latency and an attached database — which, for user-facing app backends, is usually the side of the trade the users can feel.

Frequently asked questions

What is a cold start?

The extra latency when a serverless platform must build a fresh execution environment before running your function: allocate an instance, download your code, boot the runtime, run your initialization code — and only then handle the request. A warm start skips straight to the last step.

How long does a cold start take?

Typically a hundred milliseconds to over a second. Interpreted runtimes (JavaScript, Python) land around 200–400 ms; compiled ones (Go, Rust) can dip below 100 ms; VM-based runtimes (JVM, .NET) run 500 ms to several seconds, with framework-heavy setups worst. Tail latencies run two to three times the median.

What causes cold starts?

Scale-to-zero economics: idle environments are reclaimed so you pay nothing at rest, which means the first request after idleness — or after a deploy, or above the current warm pool during a traffic spike — must wait for a new environment to initialize. The billing model and the latency are the same coin.

What is the difference between a cold start and a warm start?

A warm start reuses a frozen-but-initialized environment: the platform thaws it and calls your handler, adding single-digit milliseconds. Everything outside the handler — connections, caches, loaded modules — survives, which is why initialization discipline pays off across every warm invocation after.

How often do cold starts happen?

Both answers are true: under about one percent of invocations for steady production traffic — and the overwhelming majority for sparse traffic, since a function called hourly cold-starts nearly every time. Bursts add more: each concurrent request above the warm pool triggers its own cold start.

How do you reduce cold starts?

Climb the ladder from free to paid: shrink the deployment bundle and prune dependencies (the biggest free win), lazy-load rarely used imports, pick a faster runtime, raise memory (CPU scales with it), use snapshot-restore where offered — and only then pay for pre-warmed capacity.

What is provisioned concurrency?

The paid fix, also sold as minimum instances: the platform keeps N environments initialized ahead of demand, eliminating cold starts for traffic up to N. The irony is priced in — you reintroduce always-on cost to a pay-per-use model, which is why it belongs on latency-critical paths only.

Do keep-warm pings work?

Partially, and fragilely: a scheduled ping keeps one environment warm, but does nothing when concurrency scales out — the tenth simultaneous request cold-starts no matter how warm the first environment is. Warmers are the legacy hack; minimum instances are the supported answer.

Which runtimes have the fastest cold starts?

Compiled-to-native first (Rust, Go), interpreted next (JavaScript, Python), VM-with-JIT last (.NET, JVM) — though snapshot-restore features cut JVM cold starts dramatically. Bundle size often matters as much as the runtime: heavy dependency trees measurably multiply startup.

Do cold starts actually matter for my app?

Only where a human is waiting: synchronous, user-facing hot paths like interactive APIs and payments. Queues, webhooks, scheduled jobs, and other async work absorb cold starts invisibly. Measure tail latency under production-like traffic before spending money on the problem.

Related terms

Compare with

Further reading

Ready to build your backend?

Start your project on Back4app in minutes — database, auth, APIs, and Cloud Code included. No credit card required.

Written and reviewed by Back4app Engineering, Back4app Engineering · Published 2026-07-30