Your metal. Machines on demand.
Linux VMs that manage themselves. Create in seconds, snapshot everything, resume in milliseconds. On your hardware, open source.
curl -fsSL bhatti.sh/install | sudo bash Real machines. Zero waste.
Real VMs. Not containers.
Every machine runs its own Linux kernel. Separate filesystem, separate network, separate process space. Not a namespace trick — a separate computer.
Snapshot everything. Not just files.
When bhatti snapshots a machine, it captures everything: running processes, open file descriptors, TCP connections, in-memory state. Resume picks up exactly where it left off.
Idle machines cost nothing.
Idle machines pause their CPUs automatically. Left idle longer, they snapshot to disk and free all memory. Any request wakes them transparently — you never manage this.
| Operation | p50 | p99 |
|---|---|---|
| Create a machine | 266ms | 291ms |
| Snapshot to disk (1024MB) | 485ms | 807ms |
| Wake on request (cold) | 360ms | 430ms |
| Wake on request (warm) | 3.7ms | 10.2ms |
| Destroy a machine | 87ms | 96ms |
| Run a command | 12ms | 14ms |
| 20 commands in parallel | 32ms | 39ms |
Hetzner AX102, btrfs, bhatti v1.11.0, CLI on the daemon host.
Reproduce: bench/run.sh.
How it works
Click any component to explore.
What people use it for
One sandbox per AI agent
The original use case for bhatti. Each agent gets its own Linux VM. Snapshot at any tool call so you can branch from that exact moment if the run goes sideways.
# Each agent gets its own Linux VM
$ bhatti create --name agent --image ai
sandbox/agent created (2 vCPU, 2048 MB)
# Snapshot before a risky tool call
$ bhatti snapshot create agent --name pre
✓ checkpoint "pre" created (2048MB)
# Run goes sideways? Branch from there:
$ bhatti snapshot resume pre --name retry
✓ restored, state intact
# 40 agents on a Pi; idle ones go cold
$ bhatti list | grep agent | wc -l
40 Preview environments per PR, free when idle
One sandbox per pull request. `bhatti publish` gives it a public URL with TLS. Idle previews pause themselves, snapshot to disk after thirty minutes, and wake on the next request in ~50 ms. No rented infrastructure.
# CI spins up a preview from your image
$ bhatti create --name pr-247 --image base
$ bhatti exec pr-247 -- ./deploy.sh
$ bhatti publish pr-247 -p 3000
Published: https://pr-247.bhatti.sh
# Days later — the sandbox is cold
$ bhatti list
NAME STATUS THERMAL URL
pr-247 stopped cold https://...
# Reviewer opens the URL — auto-wake
$ curl -s https://pr-247.bhatti.sh
{"build":"ok"} # wake + serve, ~50ms Anything you can rootfs is yours
OCI pull, Docker import, or save a running sandbox. Whatever you put in a rootfs becomes a Linux VM that snapshots, resumes, and idles for free. Postgres, browser automation, full desktops — it all just works.
# Pull an OCI image as a rootfs
$ bhatti image pull ghcr.io/myorg/devbox
✓ pulled, converted (820MB)
# Or import a local Docker image
$ bhatti image import my-app:latest
✓ imported
# Or save a running sandbox as a base
$ bhatti image save dev --name stack
✓ saved "stack" (1024MB)
# Whichever path — snapshottable real VM
$ bhatti create --name web --image stack
$ bhatti snapshot create web --name ready
✓ checkpoint "ready" created (1024MB) Every command
Single binary. bhatti serve starts the daemon, everything else talks to its API.
Run it on your hardware.
One command. Any Linux machine with KVM. Downloads pre-built binaries, a kernel, and an Ubuntu 24.04 rootfs. No Docker, no containers, no orchestration layer.
Requirements
- Linux (x86_64 or ARM64)
- Hardware virtualization (/dev/kvm)
- Root access for daemon (Firecracker requirement)
Running on: two Raspberry Pi 5s with NVMe HATs at home, a Hetzner AX102 in production.
# Install on any Linux box with KVM
$ curl -fsSL bhatti.sh/install | sudo bash
==> Installing bhatti (server, minimal tier)
✓ Firecracker + jailer
✓ bhatti, lohar, kernel, rootfs
✓ admin API key in ~/.bhatti/config.yaml
✓ bhatti.service started
# Create a sandbox — no setup step needed
$ bhatti create --name dev
sandbox/dev created (1 vCPU, 1024 MB)
$ bhatti exec dev -- uname -a
Linux dev 6.1.155 #1 SMP aarch64 GNU/Linux
# Add a teammate; let them drive it remotely
$ sudo bhatti user create --name alice
bht_alice_abc123...
# Then on their machine:
$ bhatti setup --url https://api:8080 \
--token bht_alice_abc123
✓ authenticated (0 sandboxes) Documentation
Quickstart
Install, configure, and run your first sandbox in two minutes
→Self-Hosting
Install the daemon on your own hardware
→CLI Reference
Every command, global flags, environment variables
→API Reference
REST endpoints with curl examples
→Configuration
Server config, layered loading, data dir layout
→Architecture
System design, data flow, concurrency model
→Thermal States
Hot/warm/cold transitions and diff snapshots
→Networking
Per-user bridges, TAP devices, kernel ip=
→Wire Protocol
Binary framing, connection lifecycle, auth
→