An AWS Lambda like execution platform built on Firecracker microVMs exploring microVM isolation, snapshot-based cold starts, IPC, and multi-tenant scheduling.
This project is a high performance serverless execution platform that runs user submitted functions inside isolated Firecracker microVMs. It demonstrates how modern serverless platforms like AWS Lambda work under the hood, with a focus on low-latency execution, strong isolation, and high throughput.
- Each function runs inside a dedicated Firecracker microVM
- Minimal attack surface using a custom kernel and rootfs
- Stronger isolation compared to traditional containers
Pre-initialized VM state is snapshotted and restored on each invocation, dramatically reducing startup time:
| Boot Method | Latency |
|---|---|
| Cold boot | 200ms |
| Snapshot restore | 1–5ms |
- Host ↔ VM communication via vsock
- Internal routing via Unix domain sockets
- Eliminated per request connection overhead for better throughput
- Node.js based runtime executing user handlers
- Deterministic execution model: 1 request → 1 execution → response
- Handles success, errors, and malformed input
- Manages function deployment and VM lifecycle (create, snapshot, restore, destroy)
- Routes invocations and enforces execution boundaries and resource limits
- Per function queues with concurrency control
- Fair scheduling across multiple concurrent workloads
The control plane manages deployment, scheduling, snapshot orchestration, and request routing. Functions execute inside isolated Firecracker microVMs communicating with the host via vsock.
- User deploys function code
- System builds a minimal rootfs containing the user code
- Firecracker VM boots and the runtime initializes
- A snapshot of the initialized VM state is created
- On each invocation:
- Pre warm VM is used
- If no warm VM is present then a VM is restored from the snapshot
- Request is sent via vsock
- Runtime executes the handler
- Response is returned to the client
- Linux host with KVM support (
/dev/kvmmust be accessible) - Firecracker binary in
PATH - Node.js v18+ and npm
Pre built demo assets are available in the Beta release:
| Asset | Download |
|---|---|
| Linux kernel image | vmlinux |
| Root filesystem | rootfs.ext4.gz |
Download and place them in the project root:
wget https://github.com/vivek1504/serverless-runtime/releases/download/Beta/vmlinux
wget https://github.com/vivek1504/serverless-runtime/releases/download/Beta/rootfs.ext4.gz
# Extract the rootfs
gunzip rootfs.ext4.gzgit clone https://github.com/vivek1504/serverless-runtime.git
cd serverless-runtime
# directories to store usercode and snapshots
mkdir extracted mem rootfs snapshot userCode
# log file for firecracker.log
touch firecracker.log
npm installStart the control plane:
npm start
# listening on http://localhost:3000Your function must export a handler using serverless-http — app.listen is not supported inside a microVM. Wrap your Express (or any Node.js HTTP framework) app like so:
// app.js
const express = require('express');
const serverless = require('serverless-http');
const app = express();
app.get('/', (req, res) => {
res.send('Hello from Firecracker!');
});
module.exports.handler = serverless(app);Zip your project with node_modules included:
zip -r function.zip . # node_modules must be inside the zipNote: The runtime has no network access to install packages, so
node_modulesmust be bundled inside the zip.
Send the zip as a multipart form upload to /deploy:
curl -X POST http://localhost:3000/deploy \
-F "code=@function.zip"Response:
{
"functionId": "44ca883e56733724",
"status": "deployed",
"snapshotReady": true,
"url": "http://localhost:3000/f/44ca883e56733724"
}Use the url returned from the deploy response to invoke your function:
curl http://localhost:3000/f/44ca883e56733724You can also pass a path or body depending on your handler's routing:
curl -X POST http://localhost:3000/f/44ca883e56733724/greet \
-H "Content-Type: application/json" \
-d '{ "name": "John Doe" }'With the control plane running and a function deployed, run the autocannon benchmark:
npx autocannon -c 10 -d 30 -m POST \
-H "Content-Type: application/json" \
-b '{ "name": "John Doe" }' \
http://localhost:3000/f/44ca883e56733724This replicates the benchmark configuration used to produce the performance numbers in this README (10 concurrent connections, 30-second duration).
Benchmarked using autocannon with 10 concurrent connections over 30 seconds:
| Metric | Result |
|---|---|
| Throughput | ~5,400 req/sec |
| p50 latency | ~1ms |
| p99 latency | ~4ms |
| Total requests | ~164,000 |
Key optimizations: snapshot reuse, persistent runtime, reduced IPC overhead.
| Component | Technology |
|---|---|
| MicroVMs | Firecracker |
| Control plane & runtime | Node.js / Express |
| Virtualization | Linux (KVM, namespaces) |
| Host ↔ VM IPC | vsock |
| Intra-VM IPC | Unix domain sockets |
| Benchmarking | autocannon |
| Aspect | Decision |
|---|---|
| Latency | Warm execution reuse for low latency |
| Isolation | Strong VM isolation; runtime reuse introduces shared state |
| Throughput | Optimized for high throughput over strict per-request isolation |
- Per function autoscaling
- Rate limiting and priority scheduling
- Distributed execution across multiple hosts
This project demonstrates:
- Deep understanding of OS-level virtualization
- Practical use of Firecracker and microVMs
- Handling of real-world concurrency challenges
- Thoughtful tradeoffs between latency, isolation, and throughput
- System design comparable to production serverless platforms
Vivek Jadhav — github.com/vivek1504

