Cold vs. warm boot on a Babashka custom runtime (via blambda)
Three numbers, one log line
Every Lambda invocation ends with a REPORT line in CloudWatch:
REPORT RequestId: ... Duration: 4.60 ms Billed Duration: 5 ms Memory Size: 512 MB Max Memory Used: 237 MB [Init Duration: 322.20 ms]
- Init Duration (cold invokes only): time to start the execution environment — mount the runtime layer, exec
bootstrap, start thebbbinary, interpretbootstrap.clj,requirethe handler namespace — before the handler's first request is served. - Duration: the handler's own execution time (the Runtime API loop's
next-invocation→handler→send-response!round trip). Present on every invocation, cold or warm. - Billed Duration: what you're actually charged for. For a custom runtime this includes Init Duration on a cold invoke.
bb invoke prints this line directly. script/bench.clj's parse-report-line turns it into a Clojure map; Init Duration's absence is exactly how a warm sample is told apart from a cold one.
What bb bench does
For each memory tier in BENCH_MEMORY_TIERS (default 2048,3008):
aws lambda update-function-configuration --memory-size <tier>: any configuration update invalidates the function's existing execution environments, so the very next invoke runs in a fresh one. No separate "force cold start" trick needed.- Waits for the update to finish applying, then invokes once, the cold sample.
- Invokes
BENCH_WARM_SAMPLESmore times back-to-back (no further config change), the warm samples, landing on the same execution environment. - Prints a table: Cold Init Duration, Cold Duration, Warm Duration (min/median/max), Max Memory Used, one column per tier.
Run it:
bb deploy
bb bench
bb teardown # when you're done -- nothing should keep running in your account
Two things worth knowing before you run it. bb bench leaves the function configured at its last tier's memory size (3008 MB by default): a later bb deploy resets it back to 2048 MB, but if you only ever run bb bench you're left on the higher-cost tier until you set it back yourself. And bb deploy/bb bench/bb teardown all act on whatever function/role name is configured (LAMBDA_MVP_FUNCTION_NAME, default lambda-mvp-bb) — the runtime layer name stays fixed regardless — so don't point it at an existing unrelated resource.
If a "cold" sample shows no Init Duration, bb bench prints a warning rather than silently reporting incomplete data.
This project's own baseline
Measured against a real deployment (ap-southeast-2, arm64, provided.al2023, 2026-09-13), via bb bench with the default tiers and sample count:
| Metric | 2048 MB | 3008 MB |
|---|---|---|
| Cold Init Duration | 380.7 ms | 368.6 ms |
| Cold Duration | 7.7 ms | 7.0 ms |
| Warm Duration (min/median/max) | 1.7 / 1.8 / 1.8 ms | 1.7 / 1.7 / 1.9 ms |
| Max Memory Used | 102 MB | 104 MB |
As with every sibling's own recorded table: illustrative, not a live guarantee — a single run, on one account, one region, one day. Your numbers will differ by account, region, and the hardware allocation AWS happens to give you. Run bb bench for your own.
A second run, 2026-09-19
The table above stays as recorded. This one is a fresh bb bench against the same account and region six days later, taken while the lambda-mvp-* family was re-measured together after jolt shipped v0.8.9. Nothing about this project changed between the two runs, so the gap between them is a useful read on how much of any sibling's movement is just AWS:
| Metric | 2048 MB | 3008 MB |
|---|---|---|
| Cold Init Duration | 397.6 ms | 370.8 ms |
| Cold Duration | 8.1 ms | 8.2 ms |
| Warm Duration (min/median/max) | 1.8 / 1.9 / 2.0 ms | 1.8 / 1.8 / 2.1 ms |
| Max Memory Used | 104 MB | 104 MB |
Cold Init landed within 5% of the 2026-09-13 figures at both tiers (4.4% at 2048 MB, 0.6% at 3008 MB) and Max Memory Used within 2 MB, which is the reassuring outcome. Cold Duration sat slightly higher, 8.1-8.2 ms against 7.0-7.7 ms, still the highest of the five siblings and still consistent with the interpreted-handler explanation the five-way comparison gives.
See also
- Five-way comparison: this project's numbers alongside all four siblings'.
- Building the runtime layer: the two-artifact build this project's cold start goes through.