A cold start is the additional latency that occurs when a serverless platform must create a new execution environment for a function before it can process a request. The platform allocates an isolated sandbox, loads the runtime, downloads the code and runs the function’s initialization logic, and only then executes the handler. A request served by an environment that already exists is a warm start and skips all of these steps.
Cold starts are a direct consequence of the serverless model in the cloud: because the provider scales to zero and bills only for execution, idle environments are eventually reclaimed. The next request after a quiet period, and every request that arrives faster than existing environments can absorb, pays the initialization cost.
What happens during a cold start
A cold start consists of several phases, some controlled by the provider and some by the developer. The provider prepares the sandbox, typically a lightweight virtual machine or container, and attaches networking. The function package or container image is fetched, the language runtime starts, and the code outside the handler runs once. That last phase, the init phase, is where developer choices matter most.
The table below breaks a cold start into its phases and shows who controls each one.
| Phase | Work performed | Controlled by |
|---|---|---|
| Sandbox creation | Isolated microVM or container is allocated | Provider |
| Code download | Package or image layers are fetched and unpacked | Mostly provider, size by developer |
| Runtime start | Interpreter or virtual machine boots | Provider, choice of runtime by developer |
| Initialization code | Imports, SDK clients, configuration loading | Developer |
| First invocation | Handler runs, lazy paths are compiled or loaded | Developer |
After the request completes, the environment usually stays alive for a period the provider does not guarantee, often minutes rather than hours. Further requests reuse it, keeping database connections, caches and loaded libraries in memory. Each environment typically processes one request at a time in function as a service platforms such as AWS Lambda, so concurrency also drives cold starts.
Factors that determine cold start duration
Cold start latency ranges from well under 100 milliseconds for small functions in lightweight runtimes to several seconds for large packages with heavy frameworks. The exact figure depends on the provider, region and configuration, so published numbers should be treated as indicative, not fixed.
| Factor | Effect on cold start | Typical lever |
|---|---|---|
| Runtime language | Interpreted and native runtimes start faster than JVM or .NET without tuning | Choose runtime, use snapshots or native compilation |
| Package size | Larger artifacts take longer to fetch and load | Remove unused dependencies, tree-shake bundles |
| Memory setting | More memory usually brings proportionally more CPU | Raise memory for CPU-bound initialization |
| Initialization logic | Eager loading of SDKs and configuration adds time | Lazy-load rarely used modules |
| Network attachment | Private network setup once added notable delay | Use current platform networking, avoid extra hops |
| Container images | Large images increase fetch time | Use slim base images and layer caching |
The memory setting deserves particular attention. On several platforms, CPU share scales with memory, so a function configured with the minimum memory may initialize several times more slowly than the same function with more memory, sometimes at a similar total cost because it finishes faster.
Cold starts compared with related latency effects
Cold start is often confused with other sources of slowness. Distinguishing them avoids optimizing the wrong layer.
| Effect | When it occurs | Distinguishing sign |
|---|---|---|
| Cold start | New execution environment is created | Only some requests are slow, mostly after idle periods or bursts |
| Warm start | Existing environment is reused | Consistently low overhead |
| Throttling | Concurrency limit is reached | Errors or retries rather than slow success |
| Downstream latency | Database or API is slow | Slowness persists on warm invocations |
| Container scale-up | Orchestrator adds pods or tasks | Delays of tens of seconds, not milliseconds |
Monitoring tools usually report an init duration separately from the handler duration. Examining the percentage of invocations with a non-zero init duration, and the tail latency at the 99th percentile, shows whether cold starts actually affect users.
Techniques to reduce cold start impact
Mitigation either makes each cold start shorter or makes cold starts rarer. Provisioned concurrency, offered under various names by major providers, keeps a fixed number of environments initialized at all times, which removes cold starts up to that level but reintroduces an always-on cost. Snapshot-based features restore a pre-initialized memory image instead of running initialization again.
- Keep deployment packages small and initialize only what every request needs.
- Create SDK clients and connection pools outside the handler so warm invocations reuse them.
- Use provisioned or minimum instances for latency-critical, steady traffic paths.
- Prefer asynchronous designs with queues where users do not wait for the response.
- Avoid scheduled warming pings as the main strategy, because they keep only one environment warm and do not cover bursts.
The following decision table helps match the technique to the workload.
| Workload | Recommended approach | Reason |
|---|---|---|
| Background processing | Accept cold starts | No user waits for the result |
| Public API with steady traffic | Provisioned concurrency for the baseline | Predictable latency at known cost |
| Spiky interactive traffic | Small packages, fast runtime, snapshots | Bursts always create new environments |
| Strict low-latency service | Containers or always-on instances | Serverless scaling cannot guarantee zero cold starts |
Common misconceptions about cold starts
A frequent mistake is assuming that cold starts happen only after long idle periods. In practice, any increase in concurrent requests creates new environments, so a sudden burst of traffic causes a wave of cold starts even on a busy function. Another misconception is that cold starts dominate latency for every application; for functions invoked thousands of times per minute, they may affect well under one percent of requests.
Finally, the environment lifetime is not a contract. Providers recycle environments for maintenance, updates and capacity balancing, so code must never rely on in-memory state surviving between invocations.
Explained without jargon
Think of a food truck that closes when there are no customers. When the first customer of the afternoon arrives, the cook has to start the grill, unpack the ingredients and heat the oil before making anything. That first order takes longer. Once everything is running, the next orders come out quickly.
A cold start is that first slow order. Serverless platforms switch off unused capacity to save money, and switching it back on takes a moment. The trade-off is simple: lower cost when idle, a short wait when activity resumes.
A typical use case
A retailer runs its checkout API as serverless functions written in Java. Most requests finish in about 80 milliseconds, but monitoring shows that a few percent of requests take more than two seconds, mostly in the morning when traffic ramps up. The init duration metric confirms that these slow requests are cold starts caused by framework loading.
The team removes unused libraries, moves rarely used clients into lazy initialization and raises memory from 512 MB to 1,024 MB. It also enables provisioned concurrency of 20 environments during business hours, matching the typical morning baseline. The 99th percentile latency drops below 400 milliseconds, and the extra cost is limited to the hours when customers actually shop.