On this page

Providers

Stado's compute adapters, selection and live VM inventory. For operations see quota, marketplace and CLI.

Selection: WC_PROVIDERS

The compute provider list is providers in the selected STADO_CONFIG profile, overridable with the comma-separated WC_PROVIDERS environment variable. The order is the preference order. The default is empty: an unconfigured deployment has no provider rather than a hidden GCP dependency.

providers_disabled (env WC_DISABLED_PROVIDERS) is the explicit fence. A fenced provider stays visible in configuration — the profile can explain why a provisioned provider exists — but the scheduler never calls it.

The shared compute-adapter factory enforces the same fence before constructing a client or resolving its credentials. A provider outside the enabled list is refused too. This applies to VM inspection and lifecycle operations, including cancellation: selecting an existing instance never implicitly enables its provider. Storage-backend selection remains separate.

The coordinator resolves this list into tick arms and, per provider and per tick, checks running jobs, reaps dead agents, and schedules queued jobs. A provider whose constructor fails (credentials missing) is logged and skipped, so a misconfigured provider never blocks the primary one. local is in the list but has no cloud tick arm: device-local agents claim assigned jobs directly, and there is no VM lifecycle to schedule or reap.

Inspect the full catalog — capability families, variants, providers, and the active selections — with:

stado capabilities
stado capabilities --json

The catalog answers what a user can ask Stado to provide and which providers implement, partially support, expose externally, or plan each family (compute, workload execution, object storage, quota and capacity, billing, inventory, observability, and the rest). Compute is only one facet: the storage backend is selected separately by WC_STORAGE_BACKEND, not by WC_PROVIDERS.

What each provider contributes

A dispatch-capable cloud entry in WC_PROVIDERS rents agent VMs, and — per the capability catalog — may expose quota, pricing and inventory to the extent its adapter implements them. local contributes no provisioning at all: it attaches existing registered hosts, whose capacity comes from live CPU load, available RAM, disk gates, running jobs, and per-device free VRAM. box leases externally managed fixed-shape machines and reports account limits and available boxes. vast is not a dispatch provider: it is this fleet's own machine listed as a host on Vast.ai. Renting Vast.ai machines is the separate provider vast-rental, one of the GPU and cloud compute vendors.

Provider What Stado uses it for Where credentials live
gcp Google Compute Engine VM dispatch and reap; live accelerator quota; machine prices, BigQuery billing export, credits, budgets; GCP asset inventory Platform metadata identity where available, otherwise the stado-gcp Skarbiec item
azure Azure VM dispatch and reap; configured quota reservations; machine prices, balance, usage, billing health; Stado-owned VM inventory Azure managed identity preferred, then the stado-azure service-principal Skarbiec item
aws Amazon EC2 VM dispatch and reap; machine-price estimation; Stado-owned EC2 inventory stado-aws Skarbiec item (access_key_id, secret_access_key); IMDSv2 workload identity on adapter hosts without a grant; environment credential chains are disabled
box Leasing externally managed fixed-shape boxes; account limits and available boxes stado-box/api_key in Skarbiec
local Executing on existing registered hosts; no machine provisioning Registry SSH host keys in the selected credential store (stado fleet key); no OpenSSH-file fallback
vast The stado market --provider vast adapter: listing our own idle GPU host on the Vast.ai marketplace vast/api_key in Skarbiec
arkane Vendor machine listing, read and release; no agent dispatch because the deploy API accepts no startup script The Skarbiec item tagged stado:role:cloud-arkane
crusoe, cudo, hyperstack, lambda, latitude, nebius, oblivus, oracle, runpod, salad, scaleway, vast-rental, voltage-park, vultr GPU and cloud compute vendors: agent machine dispatch and reap, Stado-owned machine inventory; see GPU and cloud compute vendors The Skarbiec item tagged stado:role:cloud-<provider>

Cloud locators and credentials are never caller overrides: an enabled adapter receives its exact profile and provider-plugin identity, and a workload-agent grant must never contain stado-gcp, stado-azure, or stado-aws. See configuration for the credential store itself.

The reaper reads each cloud VM's own state word and places it as running, stopped or ended: on gcp the documented Compute Engine statuses, on aws the documented EC2 states (pending and running run; stopping and stopped keep their volumes; shutting-down and terminated are released). A preemptible job whose VM the provider stopped or released is put back as Spot preempted; any other job on a VM that is not running is put back as instance gone (lifecycle=<word>). On both clouds only the provider's own not-found answer reads as no VM. A state word outside the documented list, or an answer without one, is refused with the instance and the word (EC2 instance <id> returned unknown state <word>; existence cannot be decided), so the reaper stops on it instead of putting back a job whose VM may still run it.

GPU and cloud compute vendors

Fourteen GPU and cloud compute vendors dispatch agent machines like gcp, azure and aws: enable one in providers (or WC_PROVIDERS) and the coordinator dispatches, reaps and counts its agents against the reservation overlay. Arkane Cloud is the fifteenth adapter, but only lists, reads and releases vendor machines; its deploy API cannot boot an agent. The adapters share the provider-neutral VM lifecycle (providers::gpu_cloud) where their vendor API supports it.

Provider id (aliases) Vendor Settings (stado config set <path> <value>) Credential fields Agent runs
arkane (arkane-cloud) Arkane Cloud none api_key never: listed, read and released only
crusoe Crusoe Cloud crusoe.project_id, crusoe.location, crusoe.ssh_public_key; optional crusoe.image access_key_id, secret_key on the VM
cudo (cudo-compute) Cudo Compute cudo.project_id, cudo.data_center, cudo.image_id, cudo.vcpus, cudo.memory_gib api_key on the VM
hyperstack Hyperstack hyperstack.environment, hyperstack.image, hyperstack.key_name api_key on the VM
lambda (lambda-labs) Lambda Cloud lambda.region, lambda.ssh_key_name; optional lambda.image_family api_key on the instance
latitude (latitude-sh) Latitude.sh latitude.project, latitude.site; optional latitude.operating_system, latitude.ssh_key api_key on the VM
nebius Nebius AI Cloud nebius.project_id, nebius.subnet_id, nebius.image_family, nebius.jwt_lifetime_seconds service_account_id, key_id, private_key on the instance
oblivus Oblivus Cloud oblivus.location, oblivus.os_label, oblivus.os_name, oblivus.ssh_public_key api_key on the VM
oracle (oci) Oracle Cloud Infrastructure oracle.region, oracle.compartment_id, oracle.availability_domain, oracle.subnet_id, oracle.image_id; optional oracle.ssh_public_key tenancy, user, fingerprint, private_key on the instance
runpod RunPod runpod.image, runpod.cloud_type api_key inside the pod's container
salad (saladcloud) SaladCloud salad.organization, salad.project, salad.image, salad.vcpus, salad.memory_mb api_key inside the container
scaleway Scaleway scaleway.zone, scaleway.project_id, scaleway.image secret_key on the GPU Instance
vast-rental Vast.ai vast-rental.image api_key inside the instance's container
voltage-park (voltagepark) Voltage Park optional voltage-park.location api_key on the VM
vultr Vultr vultr.region, vultr.os_id; optional vultr.ssh_key_id api_key on the instance

Every setting has an environment override: the upper-case provider and key (LAMBDA_REGION, VOLTAGE_PARK_LOCATION), except Oracle's, which start with OCI_ (OCI_COMPARTMENT_ID). stado config validate refuses a profile that enables a vendor without one of its required settings, naming the path and the variable: lambda provider needs lambda.region (environment override LAMBDA_REGION).

Vast.ai is a marketplace rather than a catalogue of instance types, so vast-rental rents in two steps. For the accelerator's Vast.ai GPU name (L4, RTX 4090, RTX A6000, L40S, H100 PCIE, H100 SXM, H200) it searches the offers that are rentable, not already rented by this account, verified, on-demand, carry one such GPU and have room for the job's boot disk, and accepts the cheapest by total hourly price. An empty search is capacity, so the dispatcher moves to the next tier as it does for any vendor out of stock. The agent's startup script is the container's entrypoint (bash -c), because Vast.ai cuts the onstart field at 4,048 characters; the instance label is the agent's name and the script exports it as STADO_WORKER_NAME. An instance whose container Vast.ai reports exited, offline or unknown while it is meant to run never starts, by Vast.ai's own documentation, and is read as failed, so the reaper releases it. Use a Vast.ai API key of its own under cloud-vast-rental: it spends the account's credit, while the selling side reads the host's key.

stado config set vast-rental.image <image with bash and the agent's runtime>
stado credentials item put --host <vault host> --role cloud-vast-rental --type api-key   # {"api_key": "…"} on standard input
stado config set providers '["local", "vast-rental"]'
stado config validate
stado instances list --provider vast-rental

Credentials

A vendor's account credential is one Skarbiec item tagged stado:role:cloud-<provider> (cloud-lambda, cloud-voltage-park, …), holding the fields in the table. Store it on the vault host with the JSON object on standard input, never on the command line:

stado credentials item put --host <vault host> --role cloud-lambda --type api-key

The coordinator reads the item through its own grant; a workload grant may not carry it, and stado config validate refuses agent.skarbiec.roles or agent.skarbiec.secret_fields that name any cloud-<provider> role. A missing item is refused at the first call that needs it, naming the role and this command: Lambda Cloud: no live Skarbiec item tagged stado:role:cloud-lambda carries a non-empty field api_key; store the Lambda Cloud credential with stado credentials item put --host <vault host> --role cloud-lambda --type api-key and the JSON object on standard input. A vendor that refuses the credential is reported with the role and the vendor's own answer: Lambda Cloud: list instances: the credential in Skarbiec role cloud-lambda was refused (HTTP 401): ….

How many machines run

No vendor exposes a quota Stado can read, so the reservation overlay is the ceiling: config/quotas.json in the queue store declares, per vendor and accelerator, how many machines may run at once. A vendor with no section dispatches nothing, and stado doctor says so: lambda: has no quota API, and config/quotas.json in the queue store declares no lambda section, so no lambda machine is ever dispatched.

The operator declares total from its capacity agreement and reserved from capacity it has committed elsewhere under the chosen vendor and accelerator keys. Stado chooses neither count.

Each vendor declares the instance types it offers and the accelerator each carries; a job's VRAM need selects the smallest offer whose accelerator memory covers it, and a vendor that reports no capacity for a type moves the job to the next larger offer. Lambda, Vultr, Voltage Park and Crusoe report capacity before a launch (Vultr's region availability, Voltage Park's instant presets, Crusoe's capacities, Lambda's insufficient-capacity code); Scaleway's out_of_stock refusal is capacity too. Machines are rented on demand only; a preemptible request is refused.

Provider Instance type → accelerator
crusoe l40s-48gb.1x → nvidia-l40s, a100-80gb.1x → nvidia-a100-80gb, h100-80gb-sxm-ib.8x → nvidia-h100-80gb, h200-141gb-sxm-ib.8x → nvidia-h200-141gb
cudo epyc-milan-rtx-a6000 → nvidia-rtx-a6000-48gb, epyc-milan-a100-pcie → nvidia-tesla-a100, sapphire-rapids-h100 → nvidia-h100-80gb
hyperstack n3-RTX-A6000x1 → nvidia-rtx-a6000-48gb, n3-L40x1 → nvidia-l40-48gb, n3-A100x1 → nvidia-a100-80gb, n3-H100x1 → nvidia-h100-80gb, n3-H100-SXM5x8 → nvidia-h100-80gb
lambda gpu_1x_a10 → nvidia-a10, gpu_1x_rtx6000 → nvidia-rtx6000-24gb, gpu_1x_a100_sxm4 → nvidia-tesla-a100, gpu_1x_a100 → nvidia-tesla-a100, gpu_1x_a6000 → nvidia-rtx-a6000-48gb, gpu_1x_h100_pcie → nvidia-h100-80gb, gpu_1x_h100_sxm5 → nvidia-h100-80gb, gpu_8x_a100_80gb_sxm4 → nvidia-a100-80gb, gpu_8x_v100 → nvidia-tesla-v100-16gb
latitude g3.l40s.medium → nvidia-l40s, g3.h100.large → nvidia-h100-80gb
nebius gpu-l40s-a/1gpu-8vcpu-32gb → nvidia-l40s, gpu-h100-sxm/1gpu-16vcpu-200gb → nvidia-h100-80gb, gpu-h200-sxm/1gpu-16vcpu-200gb → nvidia-h200-141gb
oblivus RTX_4090_x1 → nvidia-rtx-4090-24gb, RTX_A6000_x1 → nvidia-rtx-a6000-48gb, L40_x1 → nvidia-l40-48gb, A100_PCIE_80GB_x1 → nvidia-a100-80gb, H100_PCIE_80GB_x1 → nvidia-h100-80gb
oracle VM.GPU.A10.1 → nvidia-a10, VM.GPU3.1 → nvidia-tesla-v100-16gb, VM.GPU.L40S.1 → nvidia-l40s, BM.GPU.A100-v2.8 → nvidia-a100-80gb, BM.GPU.H100.8 → nvidia-h100-80gb
runpod NVIDIA L4 → nvidia-l4, NVIDIA GeForce RTX 4090 → nvidia-rtx-4090-24gb, NVIDIA RTX A6000 → nvidia-rtx-a6000-48gb, NVIDIA L40S → nvidia-l40s, NVIDIA A100 80GB PCIe → nvidia-a100-80gb, NVIDIA A100-SXM4-80GB → nvidia-a100-80gb, NVIDIA H100 80GB HBM3 → nvidia-h100-80gb, NVIDIA H100 PCIe → nvidia-h100-80gb, AMD Instinct MI300X OAM → amd-mi300x-192gb
salad RTX 3090 (24 GB) → nvidia-rtx-3090-24gb, RTX 4090 (24 GB) → nvidia-rtx-4090-24gb, RTX 5090 (32 GB) → nvidia-rtx-5090-32gb
scaleway L4-1-24G → nvidia-l4, L40S-1-48G → nvidia-l40s, H100-1-80G → nvidia-h100-80gb
voltage-park h100-sxm5-80gb → nvidia-h100-80gb, h200-sxm5-141gb → nvidia-h200-141gb
vultr vcg-a40-8c-40g-16vram → nvidia-a40-16gb, vcg-a40-12c-60g-24vram → nvidia-a40-24gb, vcg-l40s-16c-180g-48vram → nvidia-l40s

When two offers carry accelerators of the same memory, the one listed first is the one a job is sized onto; the others are still counted when they run.

The agent on a rented machine

Every machine boots the same provider-neutral startup script the other clouds use, delivered as the vendor's cloud-init, user data, start script or container command. On a virtual or bare-metal machine the script first sets the hostname to the instance name (wisent-agent-<accel>-<tick>-<n>). A container cannot set its hostname, so on RunPod and SaladCloud the script exports STADO_WORKER_NAME instead — the instance name on SaladCloud, the pod id from RUNPOD_POD_ID on RunPod — and the agent publishes capacity under that name. The reaper matches the same name, and only machines whose name starts with the fleet's instance prefix are treated as agents; anything else the credential can see is left alone.

Arkane Cloud's deploy API takes no startup script, so no agent can boot there. Its machines are listed, read and released, it has no sizing ladder, the coordinator gives it no dispatch arm, and a launch is refused: Arkane Cloud: the vendor's deploy API takes no startup script, so Stado cannot boot an agent on a machine it rents there; arkane machines are listed, read and released but never dispatched.

Azure operator sign-in and role repair

Read Azure operator sign-in and role repair.

Quota

Read quota diagnostics and operations for live capacity, requests, refusals and Desktop confirmation.

Live instances

stado instances list shows live agent VMs across the configured providers and flags ones no queue job or lease still references. Its operational inventory path can publish expired capacity records. For a read-only census that makes no capacity publication, use stado resources show --provider <provider> --json; its compute row names the vendor's enumeration state and error instead of reporting an inaccessible fleet as empty.

stado resources show --provider gcp --json
stado instances list --provider gcp --json

--provider cannot expand the enabled set. A fenced selection returns PROVIDER_DISABLED; a provider absent from the enabled list returns PROVIDER_NOT_ENABLED. These refusals happen before queue or credential reads. The command exits 1. With --json, its error envelope contains status: "error", error_code: "refused", retryable: false, and a message naming the provider and the governing configuration field.

The resource inventory uses the same compute-adapter boundary. Its refused provider row stays blocked, with unknown instance and orphan counts and the reason attached; it is not evidence of an empty fleet. Cancellation retains the refusal instead of reporting a remote instance deleted.

Reaping runs on each coordinator tick, including autonomy.

Offering idle GPUs on a marketplace

The Vast.ai host marketplace lists this fleet's idle GPU. Buying machines is the separate vast-rental compute provider.

The provider-neutral rule

Every command above enters through Stado. Provider diagnostics belong inside the corresponding adapter and are unavailable unless that provider is explicitly enabled in the selected profile. Nothing falls back to a cloud CLI, provider SDK, direct bucket URL, ambient credential, or a different backend: stado overview resolves only the configured Stado backend and enabled adapters, and no bootstrap, health, recovery, or release path invokes gcloud, gsutil, or az. The operational consequences are in operations.

Source: this website