📝 Companion code for the blog post: AWS Lambda MicroVMs – Einstieg (German).
A minimal Node.js 24 / TypeScript server you deploy to AWS Lambda MicroVMs in a few minutes, then poke, shell into, and benchmark. The point isn't the app — it's seeing how MicroVMs actually behave when you spin one up, hit it, and load-test it.
Measurements and notes are in docs/microvm-findings.md: throughput limits, the snapshot warm-state and Math.random() behaviour, disk I/O, and runtime logging.
⚠️ Largely vibe-coded. Built fast with an AI pair to explore the platform, not to ship. The findings are real and measured; the code is a sandbox. Fork it, break it, measure your own numbers.
App API (port 8080):
| Endpoint | What |
|---|---|
GET / |
Hello, World! |
PUT / GET / DELETE /items/{id} |
tiny object API, DynamoDB-backed |
GET /rand |
snapshot-uniqueness demo: two VMs from the same snapshot return the same Math.random() sequence, but different crypto.randomBytes() |
In the VM: a shell, diskbench (fio disk I/O), htop/mpstat for CPU under burst.
From outside: a k6 load test that finds the real requests/second ceiling.
Region eu-west-1 only (MicroVMs isn't everywhere). You need AWS creds for the account (e.g. SSO) and a one-time CDK bootstrap.
cd cdk
npm install
npx cdk bootstrap aws://<account-id>/eu-west-1 # once per account/region
npx cdk deploy # creates the image + DynamoDB table + rolesThe image build is asynchronous. Poll until it says CREATED:
IMG=$(aws cloudformation describe-stacks --stack-name MicrovmImageStack \
--query "Stacks[0].Outputs[?OutputKey=='ImageArn'].OutputValue" --output text)
aws lambda-microvms get-microvm-image --image-identifier "$IMG" --query statenode scripts/run-microvm.ts # starts a MicroVM, smoke-tests GET /, prints microvmId + endpoint
node scripts/run-microvm.ts --shell # also attach a shell — open it in the Lambda console's "Shell" tabMint a token (≤ 60 min) and hit the API:
MVM=microvm-… # from the run-script output
EP=<id>.lambda-microvm.eu-west-1.on.aws # from the run-script output
TOKEN=$(aws lambda-microvms create-microvm-auth-token \
--microvm-identifier "$MVM" --expiration-in-minutes 30 \
--allowed-ports '[{"port":8080}]' \
--query 'authToken."X-aws-proxy-auth"' --output text)
AUTH=(-H "X-aws-proxy-auth: $TOKEN" -H "X-aws-proxy-port: 8080")
curl "https://$EP/" "${AUTH[@]}" # Hello, World!
curl -X PUT "https://$EP/items/foo" "${AUTH[@]}" -d '{"a":1}' # store → DynamoDB
curl "https://$EP/rand" "${AUTH[@]}" # snapshot-uniqueness demoStop it with aws lambda-microvms terminate-microvm --microvm-identifier "$MVM", or just let it idle-suspend.
# inside the VM shell (run-microvm.ts --shell):
diskbench # fio disk I/O matrix
htop # watch the burst cores under load
# from outside — run the k6 load test against the object API (needs k6):
npm run loadtest -- --microvm-id microvm-…src/ the app — GET /, /items, /rand, lifecycle hooks, the snapshot probe (boot.ts)
cdk/ the MicroVM image as infrastructure (CDK) — see cdk/README.md
scripts/ run-microvm.ts (start / shell / smoke-test), loadtest-microvm.ts (k6)
tools/ diskbench.cjs (baked into the image)
k6/ the /items load test
docs/ microvm-findings.md ← the interesting part
MIT A vibe-coded playground — use at your own risk.