In Part 1 I covered why Rust on AWS Lambda is worth exploring and laid out the project setup. This post measures the one number that matters most for serverless latency: cold start time. To get a clean floor measurement, I used the simplest possible endpoint with no database, no external calls, and no middleware.

The Benchmark Setup

The handler is a single health endpoint built with Axum and Cargo Lambda:

use axum::Router;
use axum::http::StatusCode;
use axum::routing::get;
use lambda_http::{Error, run};

#[tokio::main]
async fn main() -> Result<(), Error> {
    run(Router::new().route("/health", get((StatusCode::OK, "Healthy".to_string())))).await
}

The release profile is tuned for a small, fast binary:

[package]
name = "fulgurion-lambda"
version = "0.1.0"
edition = "2024"

[dependencies]
lambda_http = { version = "1" }
axum = { version = "0.8", features = ["macros"] }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }

[profile.release]
opt-level = 3
lto = "fat"
codegen-units = 1
strip = true

The lto, codegen-units, and strip flags matter here. Link-time optimization and single codegen unit produce a smaller, tighter binary. Stripping debug symbols removes anything the Lambda runtime does not need. The result, cross-compiled for Lambda’s ARM64 runtime:

cargo lambda build --compiler cross --release --arm64

Uploaded package size: 885.7 kB.

The Results

I used oha to fire 5 parallel requests, forcing 5 simultaneous cold starts:

oha -n 5 -c 5 https://redacted.execute-api.us-east-1.amazonaws.com/health

Lambda’s structured log for each invocation:

REPORT RequestId: e85978b8-96f3-4a0e-9511-c22672da4f02 Duration: 1.44 ms Billed Duration: 20 ms Memory Size: 512 MB Max Memory Used: 16 MB Init Duration: 18.45 ms
REPORT RequestId: a6953d6e-d437-466a-9273-480faf5db2dc Duration: 1.49 ms Billed Duration: 21 ms Memory Size: 512 MB Max Memory Used: 16 MB Init Duration: 18.91 ms
REPORT RequestId: 7e151036-c109-405d-a9ba-2f81b0f7a1e1 Duration: 1.75 ms Billed Duration: 25 ms Memory Size: 512 MB Max Memory Used: 16 MB Init Duration: 22.43 ms
REPORT RequestId: 19ed8d7f-85fe-4c80-a530-7b44f429a8d5 Duration: 1.93 ms Billed Duration: 25 ms Memory Size: 512 MB Max Memory Used: 16 MB Init Duration: 22.24 ms
REPORT RequestId: c4fa04e9-d361-4fe4-9a09-cbaf67f57f29 Duration: 1.63 ms Billed Duration: 22 ms Memory Size: 512 MB Max Memory Used: 16 MB Init Duration: 19.43 ms

Init duration ranges from 18 to 22 ms. Handler invocation stays under 2 ms. Memory usage peaks at 16 MB across all five environments.

What Cold Start Means Here

A cold start happens when Lambda has no warm execution environment to reuse and must provision one from scratch before running your handler. The Init Duration field in the logs above is the cost of that provisioning. AWS bills for it on top of the handler duration.

For a warm invocation the cost is ~1.5 ms. A cold start adds ~20 ms of init on top of that. For a user-facing endpoint, that difference is perceptible.

How These Numbers Compare

These results line up with the broader landscape. lambda-perf by Maxday benchmarks cold start P50 and P99 across languages, memory tiers, and CPU architectures. Rust consistently sits at the low end alongside Go and C++, well below JVM or interpreted runtimes.

The 16 MB memory footprint is also worth noting. Lambda pricing is based on GB-seconds, so a Rust function at 16 MB and 1.5 ms of handler duration costs a fraction of what an equivalent Node or Python function would, before even accounting for cold starts.

When Cold Starts Become a Problem

The numbers above are favorable, but cold starts can still hurt depending on your traffic pattern:

  • Bursty or infrequent traffic. Lambda shuts down idle execution environments. Long gaps between requests mean the next request pays the cold start cost.
  • Sudden concurrency spikes. Each concurrent in-flight request needs its own execution environment. A burst of simultaneous requests will trigger multiple cold starts at once.
  • Frequent deployments. A new deployment invalidates existing environments, forcing cold starts on the next wave of traffic.

Conclusion

For a minimal Rust Lambda, cold start lands between 18 and 22 ms with an 885.7 kB binary and 16 MB of memory. That is a strong baseline. The next post will break down what happens inside Lambda during that init window, and why each phase matters for Rust specifically.