Sovereign serverless compute

The cloud,
without the cloud.

Decorate a Python function. Run it on the machines you already own. roost ships your code to your fleet, provisions the environment once, streams the logs back, and records every run in a local ledger. No account. No upstream. No per-second meter.

~/imi — roost
$ roost run train.py::train '{"epochs": 5}'✓ building image im-8IYXJOFyr4 · uv · cached✓ created objects · train on fleet:jl1[epoch 1/5] loss=1.7412[epoch 5/5] loss=0.2183[done] checkpoints committed to volume✓ completed in 6.32s · ran_on jl1
Why roost

Modal's ergonomics. Your hardware's economics.

The same decorate-and-run workflow developers love — pointed at machines you control, with nothing hidden behind a dashboard you don't own.

source

Portable by design

roost ships your function's source plus plain-pickled args — never a code object. A run works across CPython versions, on any node, no matched interpreter required.

cache

Environments built once

Images hash to a digest that names a cached venv on each node. Unchanged image, zero rebuild — provisioned once, reused forever. Sub-5s cold builds with uv.

ledger

Radical transparency

Modal masks the host to modal. roost tells you the truth: every run records the real node it executed on. The ledger lives in ~/.roost — it's yours.

The run lifecycle

Four stages, bookended.

Every roost run streams the same shape — the client always knows where the work is.

stage 01 · build

Assemble the image

The image digest names a venv. Missing on the target? roost builds it with uv and marks it ready. Present? Skipped entirely.

stage 02 · stage

Ship source + args

Your source file, sibling modules, and pickled args are staged to the node over SSH. No cloudpickle, no version lock-in.

stage 03 · execute

Run & stream

The function runs in the provisioned env. stdout and stderr stream back live and land in the run's log files.

stage 04 · record

Commit to the ledger

Status, duration, host, and result are written to meta.json. roost runs and the console read straight from it.

roost vs. the meter

Same primitives. Different ownership.

 
Hosted serverless
roost
Where it runs
Someone else's datacenter
Your fleet — jl1, jl2, AXeServer
Cost model
Per-second, per-GB, egress
Hardware you already bought
The host
Masked to modal
Reported: ran_on jl1
The record
A dashboard you rent
A ledger you own (~/.roost)
Decorator surface
@app.function(gpu=…)
@app.function(gpu="fleet:jl1")
The console

Every run, on your own dashboard.

Run roost serve and the console reads your local ledger — per-call telemetry, live metrics, streamed logs, function config. The observability of a hosted platform, served from your laptop.

Open the console →

Bring the workload home.