Decorate a Python function. It runs on hardware you own — no Dockerfile, no cluster, no bill. The Modal model, pointed at your fleet.
# one decorator. your node. the answer comes home. import roost app = roost.App("trainer") @app.function(gpu="fleet:jl1") def train(shard): import platform return {"ran_on": platform.node(), "shard": shard} train.remote(shard=0) # blocks, hands you the result train.map([0, 1, 2, 3]) # fans out across the fleet job = train.spawn(shard=7) # detached; job.get() later
Everything the cloud made you do — the image, the registry, the cluster, the YAML — roost simply removes.
No image to build. No registry to push. The function ships as source, your data pickles, the result comes home. A laptop on Python 3.11 can drive a node on 3.14 — because roost never ships a code object, only what runs everywhere.
@app.function(gpu="fleet:jl1") def embed(batch): from model import encode # local import, shipped return encode(batch) embed.remote(batch)
Call it once and block. Or fan a whole sweep across the fleet in parallel — results returned in order. Or spawn it, pocket the receipt, and let your laptop go back to being a laptop.
An image spec hashes to a venv, cached on each node. Change nothing and it never builds again. Change one line and only that node reprovisions. No warm pools to babysit, no cold-start tax to pay twice.
Small enough to hold in your head. That’s the point.
| roost.App(name) | A namespace for related functions that share a default image. |
| @app.function(…) | Makes a function fleet-callable. Set gpu, image, volumes, timeout. |
| .remote(*a) | Run it on the fleet. Block for the result. |
| .map(iter) | Fan inputs across nodes in parallel; results returned in order. |
| .spawn(*a) | Fire and forget. Returns a handle; .get() collects it later. |
| roost.Image | A content-addressed env: base + apt + pip, hashed to a venv cached per node. |
| roost.Volume(name) | A directory that persists on a node across runs — weights, datasets, caches. |
Every call is written to a local ledger — metadata, timing, results, and the worker’s full stdout and stderr, on success or on failure. No web console to log into. It is all on the machine you already trust.
| Status | Target | Dur | Func | Run |
|---|---|---|---|---|
| success | fleet:jl1 | 27.6s | train | train-jl1-1787892153-1 |
| running | fleet:jl2 | — | train | train-jl2-1787892160-2 |
| success | local | 0.5s | eval | eval-local-1787892102-0 |
One decorator away from serverless on the hardware you already own.