Serverless
Intermediate 14 min read Serverless

Cold Starts & Function Performance

Your first request pays for the server you don't see

A cold start is the latency spike when no execution environment is warm. Init work, runtime size, memory and provisioned concurrency all shift the p95; most of the fix is architecture, not a panel.

cold startprovisioned concurrencywarminitp95snapshotruntime
Before we start

What you will learn

  • Decompose a cold start into platform init vs business init
  • Estimate the cost of runtime/language/memory choices on latency
  • Rank mitigations: lighter runtime, less init, snapshots, provisioned concurrency
In 60 seconds

Cold (no env): platform allocates, loads image and code, runs init, invokes → 100ms–1s+. Warm: invoke only → single-digit ms overhead. Tuning = shrinking init work, lighter language, or buying warm slots (provisioned concurrency).

Introduction

What is this?

Cold vs warm: env reuse. Cost components: image pull, microVM/container start, code import, init (DB connections, SDK load, config fetch). Runtimes: Node/Python warm fast; Java/.NET/Go heavier images, longer init unless SnapStart/profiled. Memory affects CPU and billed duration. Concurrency: default vs reserved vs provisioned (AWS); Azure functions always-in-plans/always-on; Cloud Run min-instances/startup CPU boost. SnapStart (Lambda) / snapshot restore (Azure) checkpoint after init to skip it.

Motivation

Why do you need it?

  • A p95 of cold-start length mangles interactive APIs regardless of code quality.
  • Every % of cold vs warm traffic is directly a latency and billing trade.
  • Choosing the right runtime may beat any warm pool in both cost and speed.
  • Snapshots can cut cold init from seconds to tens of ms without reserving capacity.
Think about it

Mental model

Imagine

A new barista starting up the espresso machine vs one who kept it running

Think of

Cold vs warm function invocation

Keeping the machine running (warm env) costs a little even when idle; new guests get their coffee faster on a running machine than a freshly-warmed one.

Mechanics

How it works

  • Invocation hits a pool; the platform maintains some warm environments.
  • No warm env → cold: allocate/load code → run top-level init → invoke.
  • Init code (imports, config, clients) runs before your handler's first line.
  • Warm envs reuse, but reuse alone doesn't persist state — memory only.
  • SnapStart freezes post-init capacity and resumes near-instantly on cold paths.

Cold vs warm timings.

Request
Cold
Warm
Response
Init budget
Hands-on

Examples

Separate init from invoke

Separate init from invoke
// top-level = runs once per cold env
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
const client = new DynamoDBClient({ region: "us-east-1" });
export const handler = async (event) => {
// per-invocation work only
const now = Date.now();
return { ok: true, t: now };
};

Heavy, slow imports and client construction live outside the handler so warm invocations skip them.

Real world

In production

  • Checkout API: provisioned concurrency over the promo window; scale-to-zero the rest of the day.
  • Media pipeline: no provision; accept seconds-latency cold handling of each frame job.
  • Java service: Lambda SnapStart/compiled images to defeat JVM cold-start pain.
Guidelines

Best practices

  • Profile init vs invoke from REPORT logs before tuning anything.
  • Lazy-load dependencies; defer or skip anything not needed on every path.
  • Prefer Node/Python for hot interactive paths unless the team needs types/JVM (SnapStart).
  • Raise memory only after proving CPU is the bottleneck — it raises duration billing too.
  • Set provisioned concurrency only for the p95-sensitive tier, never the whole fleet.
Watch out

Common mistakes

  • Adding provisioned concurrency to everything 'to be safe' and shipping the idle cost.
  • Doing DB connection + config fetch inside the handler on every call.
  • Bundling huge SDKs/packages into a single huge zip measured in tens of MB.
  • Reading p50 instead of p90/p99, where cold events actually live.
When things break

Debugging tips

  • REPORT lines show Init Duration vs Duration — the split tells you whose time is spent.
  • Plot cold-start ratio over a release: a spike after deploy is usually init creeping up.
  • Test the same operation warm vs cold 10× each and compare the spread, not averages.
  • Use X-Ray spans for 'Initialization' to see inside platform startup.
Interviews

Interview checkpoint

Practice

Hands-on lab

Measure Cold vs Warm in Your Own Function
30 min · intermediate
In progress
Objectives
  • Deploy a function with deliberate init work
  • Read REPORT logs to quantify init vs invoke
  • Apply an init-stripping fix and re-measure

Measure Cold vs Warm in Your Own Function

30 min · intermediate

0/4 steps
0%
sandbox · Linux sandbox
$
Try these commands
Test yourself

Quick quiz

0/2
1

Which is the biggest cold-start cost usually?

2

Provisioned concurrency primarily trades:

Go deeper

Official documentation