Your buckets, your bill
Bytes never pass through us. Boxes PUT and GET straight against S3, GCS, Azure Blob or any S3 endpoint with URLs signed for one object.
041 · ARTIFACTS
Versioned file sets over buckets you own
Checkpoints next to your GPUs, resumable anywhere.Your own buckets in AWS, GCP, Azure or any S3 endpoint, as one global store of versioned file sets. Every write lands in the writer's region.
Write where you train. Read across clouds, rarely.
A training run writes a checkpoint every half hour and reads one back a few times, when it resumes somewhere new. Writes into the box's own region cost nothing; sending them out of the cloud costs real money. So every write lands next to the GPUs, and the one read that crosses clouds is noise. Nothing is replicated ahead of time.
| Where the writes go | Per GB | For the run |
|---|---|---|
| A bucket in the box's own region | $0 | $0 |
| Same cloud, another region | ≈ $0.02 | ≈ $130 |
| Out of the cloud: another cloud, Tigris, R2 | ≈ $0.08–0.12 | ≈ $550–800 |
A spot run hops clouds. Its checkpoints follow it.
Writes to S3 in us-east-1. Preempted.
Reads step 500 once, across clouds. Writes to GCS in europe-west4.
Reads step 900 once. Writes to Blob in westeurope.
SkyPilot brings a preempted job back wherever GPUs are, with the same command. --resume latest opens the artifact from its latest version, which fences the old box should it still be alive, and returns that version signed. The run reads it once across clouds, then every checkpoint after lands in your bucket in the new region.
# From SexpGPU's release with o41-checkpoint, in review. # The only change to a run: the location string. $ export O41_ARTIFACTS_API_KEY=ak_… $ SEXPGPU_CHECKPOINT_DIR=o41://experiments/run-1234 \ sexpgpu run train.sx --resume latest # Preempted; SkyPilot brings it back on GCP. Same command. resumed step-00000500 from aws us-east-1 (cross-cloud) saved step-00000510 to gcp europe-west4 (region)
SexpGPU, Rust, the shell, or plain HTTP.
Every operation resolves to PUTs and GETs against S3, GCS, Azure Blob or another S3 endpoint, each signed for one object. Any language with an HTTP client can read and write, and no box ever holds a bucket key.
use o41_checkpoint::{open, step_name, Config};
let checkpoints =
open("o41://experiments/run-1234", Config::from_env()?).await?;
// The latest, or None on an empty artifact, and the one writer.
let (resumed, mut writer) = checkpoints.resume().await?;
if let Some(at) = &resumed {
let state = at.file("state.json")?.bytes().await?;
}
writer
.save(&step_name(510), files, meta) // lands in this box's region
.await?;npx @o41/artifacts login
npx @o41/artifacts ls experiments/
npx @o41/artifacts versions experiments/run-1234
npx @o41/artifacts get o41://experiments/run-1234/latest ./ckptcurl -H "Authorization: Bearer $O41_ARTIFACTS_API_KEY" \
"https://artifacts.041.io/api/v1/versions/read?artifact=experiments/run-1234&version=latest&urls=1"
# → { "version": "step-00000900", "transfer": "cross-cloud",
# "files": [{ "name": "params.safetensors", "url": "https://…" }] }Bytes never pass through us. Boxes PUT and GET straight against S3, GCS, Azure Blob or any S3 endpoint with URLs signed for one object.
Clouds connect by OIDC federation: the app is an issuer your account trusts for one subject. Revoking is deleting a role.
A region without a bucket writes to its cloud's default, then to your fallback, with a warning. A cache miss, never an error.
Every version ends with _manifest.json beside its files. Read your own bucket with your own keys if we are ever down.
Connect a cloud, pick a fallback, point a run at o41://. Questions: info@041.io