Documentation

Build on real microVMs

Everything you need to run functions on real microVMs: install, deploy, schedule, and seal your secrets.


Preview environment

The console you get when you sign up today runs on the Voopr simulation fleet: apps, deployments, logs and wake timings behave exactly like production, but no microVM is billed or executed on your behalf. Real Firecracker execution is enabled per account — contact us to be moved onto dedicated capacity.

Installation

The CLI is a single static binary. Homebrew is the fastest path on macOS and Linux; CI images can curl the release directly.

$ brew install voopr
$ curl -fsSL https://get.voopr.com | sh

First deploy

A deploy is one shot from a Git ref. The build is immutable and keyed by commit, so rolling back is a pointer move rather than a rebuild.

hello — zsh

$ voopr deploy --repo acme/hello --ref main

Built bld_9k2f · SBOM + provenance attached

Deployment dep_4q7x running

https://hello.apps.voopr.com/

$ voopr rollback --app hello --to dep_4q7w

$

Each pull request also gets pr-N.hello.apps.voopr.com with its own snapshot.

Runtimes

Each app declares one runtime. Switching runtime rebuilds the rootfs but keeps your domain, secrets and queues attached.

node24Node 24 LTS · npm, pnpm, bun install
bun1Bun 1.x · fastest install and boot
python312Python 3.12 · pip and uv
containerAny OCI image under 1 GB (Scale plan)

Regions

Snapshots are pinned to the region you pick. Requests are routed to the closest region that holds a snapshot of your app.

fra1

Frankfurt

EU data residency

iad1

Washington

US east

sin1

Singapore

APAC

$ voopr regions add sin1 --app hello

Cron & queues

Schedules and queues are wake sources like any request. A cron tick or a queue message restores the snapshot, runs the handler, and parks the app again.

hello — zsh

$ voopr cron add "0 */6 * * *" --app nightly-etl

Schedule sch_1a2b created

$ voopr queue create resize --dlq --visibility 30s

Queue resize · dlq resize-dlq

$ voopr queue push resize '{"key":"a.jpg"}' --delay 10s

$

Environment & secrets

Values are sealed at rest and injected at wake. Your code just reads an environment variable; rotation never requires a redeploy.

hello — zsh

$ voopr env set DATABASE_URL=postgres://… --app hello

DATABASE_URL sealed · injected at wake

$ voopr env rotate DATABASE_URL --app hello

Rotated · next wake picks up the new value

$

Limits

Request timeout300 s (streaming responses excluded)
Request body100 MB
Snapshot size2 GB per app
Concurrency per app1,000 microVMs (raise on request)
Cron resolution1 minute
Queue message size256 KB

CLI reference

voopr deployBuild and release from a Git ref
voopr wakeWatch wake timelines and restore latency
voopr logsStream structured logs for an app
voopr cronCreate, list and remove schedules
voopr queueCreate queues, push and inspect messages
voopr envSet, list and rotate sealed variables
voopr domainsAttach custom domains and edge rules

Error codes

VPR_401Missing or expired CLI token — run voopr login
VPR_409A deployment for this commit is already running
VPR_413Snapshot exceeds the plan size limit
VPR_429Concurrency ceiling reached for this app
VPR_503Region temporarily out of warm capacity — retried automatically