Why architecture matters here

Cold start is not a single event — it is a sequence of phases each with different costs and different levers. Some are Amazon's problem (MicroVM boot), some are yours (heavy static initialization), and some are hybrid (VPC ENIs, layer downloads). Understanding which phase costs what lets you attack the right one.

The architecture matters because ill-informed "solutions" waste money. Provisioning 100 always-warm containers when your workload runs 3 cold starts per hour is a bill mistake. Skipping SnapStart on Java because you have not read the docs is a latency mistake.

With the phases mapped, you can budget latency against dollars and pick a mitigation that fits the workload.

Advertisement

The architecture: every piece explained

The top strip is the request path. Invoke request arrives synchronously or async. Frontend + placement picks a worker; if a warm sandbox exists it routes there and skips the rest of the cold path. Otherwise Sandbox init boots a fresh Firecracker MicroVM with the function's container image or ZIP as rootfs. Runtime init starts the language runtime — JVM, Python, Node, or provided runtime — with associated bootstrap.

The middle row is the user-controlled piece. Function init runs your top-level code once — static blocks, module imports, DB connection setup, model loading. This is where 80% of controllable cold-start time hides. Handler exec is the actual per-request code. Provisioned concurrency keeps N environments pre-initialized so cold starts do not happen at all for the first N concurrent invokes. SnapStart takes a memory snapshot after init completes and restores it on cold start — a 10x speedup for Java.

The bottom rows are the trickier levers. VPC ENI attach historically added seconds to cold starts; Hyperplane ENI now amortizes this, but sizing subnets and warm ENIs still matter for high-throughput workloads. Init hooks let you register before-checkpoint and after-restore callbacks for SnapStart to handle things like DNS refresh or randomness reseed. Observability emits INIT and INVOKE durations and cold ratio; dashboards must show cold ratio per function per hour.

Lambda cold starts — init phases, provisioned concurrency, SnapStart, VPC ENIpredictable warm plus mitigated coldInvoke requestsync / asyncFrontend + placementworker selectionSandbox initMicroVM + rootfsRuntime initlanguage runtime startFunction initstatic + globals + connectionsHandler execactual request processingProvisioned conc.pre-initialized envsSnapStartrestore VM snapshotVPC ENI attachnetwork-bound cold costInit hooksbefore/after checkpointObservability — INIT duration + IN INIT vs INVOKE + concurrency + cold ratioarriveroutebootloadconnectverifyrestorewatchwatch
Lambda cold path with mitigation levers.
Advertisement

End-to-end flow

End-to-end: a first user hits a Java Spring Boot Lambda without SnapStart. Frontend picks a worker; MicroVM boots (200 ms); JVM starts (900 ms); Spring context initializes (2400 ms); handler runs (50 ms). Total: 3.5 s cold, 50 ms warm. The team turns on SnapStart. The next deploy boots init once in the pipeline and captures a snapshot. Now cold starts restore the snapshot (~250 ms) plus handler (50 ms) = 300 ms — 12x improvement. For a spiky burst, they add provisioned concurrency = 5 during business hours; the first 5 concurrent invokes have no cold cost at all. Observability shows cold ratio drops from 8% to 0.4%; cost impact is $12/month for provisioned concurrency vs previous latency SLO violations.