Cold Start

A cold start is the extra latency incurred when a serverless platform has to prepare a new execution environment before running your code. The AWS Lambda documentation identifies it as “the first two steps of downloading the code and setting up the environment,” and notes the two consequences that matter: “you are charged for this time, and it adds latency to your overall invocation duration.” Descriptions here follow that documentation, checked in September 2026.

Once an invocation completes, the environment is frozen and kept for a while; a later request that reuses it is a warm start and skips the preparation. Cold starts are therefore not a constant tax but an occasional one, which is exactly what makes them awkward to reason about.

Judge it by frequency, size, and who notices

The documented figures are a good starting point for expectations: cold starts “typically occur in under 1% of invocations,” and the duration “varies from under 100 ms to over 1 second.” Three questions turn that into a decision.

  • How often? Driven by traffic pattern and scaling. Steady traffic keeps environments warm; bursts create new ones, and a function invoked a few times a day is cold most times it runs.
  • How big? Mostly a property of your own code rather than the platform. The documentation is direct: “the largest contributor of latency before function execution comes from initialization code.”
  • Who experiences it, and against what deadline? A background job usually absorbs an extra second; it does not if the queue has a completion deadline, or if a burst of cold starts slows enough concurrent workers to build a backlog. A user-facing request is the clear case, and one that fans out to several functions can meet the penalty more than once.

One measurement caution follows from “under 1% of invocations”: an average dilutes the effect, and the percentile that reveals it depends on how often it happens. A percentile only shows a tail wider than the event’s own frequency. With 10,000 invocations where 5 take 2,100 ms and the rest take 100 ms, the mean moves to 101 ms, p99 and p99.9 both read 100 ms, and only p99.99 shows the 2,100. So monitoring the mean tells you nothing is wrong, and monitoring p99 can agree with it.

Which means the useful measurement is not a single percentile but four things together: the rate of cold starts, the initialization duration itself where the platform reports it separately, a percentile chosen above that rate, and the sample size behind it. A p99 over a hundred requests cannot resolve a 0.5% event at all.

There is also a perception trap worth knowing. The documentation observes that cold starts “are typically more common in development and test functions than production workloads,” because those are invoked less often. So the environment where developers form their impression is the one that exaggerates the problem, and the fix chosen there may be solving something production does not have.

What happens during initialization

The Init phase does three things: starting extensions, bootstrapping the runtime, and running the function’s static code — the imports, configuration, and connection setup outside the handler. By default it is limited to 10 seconds, a limit that does not apply to functions using provisioned concurrency or snapshot-based startup.

Because your static code runs here, the factors the documentation lists are all things you control: the size of the package including libraries and layers, the amount of initialization work, and how quickly libraries and other services establish connections. That is why the first place to look is the function rather than the platform.

Static initialization is also where connection reuse belongs, since objects declared outside the handler “remain initialized” for later invocations in the same environment. The balance to strike: initialize what most invocations need, and load rarely used objects lazily instead of paying for them on every cold start.

Four ways to reduce it, and what each costs

ApproachEffectCost
Trim the package and the importsLess to download and less to initialize — import the one client you use rather than a whole SDKNone worth mentioning. Do this first
Defer rarely used initializationShortens Init for the common path by loading heavy objects only when a code path needs themSlightly more code, and a slower first request on those paths
Pre-initialize environments (provisioned concurrency)The documented purpose is that it “pre-initializes execution environments, reducing cold starts” — environments are ready before requests arriveYou pay for the reserved environments whether or not they are used, which removes scale-to-zero economics
Snapshot-based startupResumes new environments from a persisted snapshot of an initialized environment instead of initializing from scratchRuntime and configuration constraints, plus care with anything captured in the snapshot that should be per-environment — a cached credential or random seed, for instance

The order in that table is deliberate. The first two are free and often sufficient; the last two trade money or constraint for predictability, and are worth it when a user-facing path has a latency commitment.

When to stop caring

Cold starts consume a disproportionate share of serverless discussion relative to their impact. Three cases usually make them unimportant — though each has a condition rather than being automatic: asynchronous work where nothing is waiting on a deadline, batch processing where initialization is a small share of a long run per run, and any path where initialization is a small fraction of the time available — a judgment to make from the measured initialization duration rather than from a round number, since initialization is not bounded by a second and a platform may re-run it.

They become important in one clear case — a synchronous user-facing request with a tight budget, especially one that chains several functions. If that is the shape of the workload, measure the high percentiles first, fix the initialization code, and only then pay for pre-initialized capacity.

How cold starts fit with the wider question of choosing between virtual machines, containers, and serverless is worked through in You Rented the Server, Not the Outcome; the statelessness the model requires is covered in stateless service.

Reference: AWS Lambda Developer Guide, Understanding the Lambda execution environment lifecycle.


Discover more from Insightful Data Lab

Subscribe to get the latest posts sent to your email.

Similar Posts

Questions, corrections, or additional insights?

This site uses Akismet to reduce spam. Learn how your comment data is processed.