gpu instances create
Create a new GPU instance
Create a new GPU instance
Synopsis
Creates a GPU instance asynchronously. The CLI polls the operation FSM until it reaches succeeded (or failed/cancelled), then fetches and prints the booted instance. Use --wait-timeout=0 to skip polling and print just the operation_id for scripts that want to poll asynchronously.
gpu instances create [flags]
Choosing a launch environment
--environment selects the launch environment (see the Certified Image guide for the full picture):
certified— launch the GPU.ai Certified Image: the one normalized, digest-pinned environment. Available only on certified-capable machines.certified:— a framework environment: a thin, digest-pinned framework layer on the certified base, with all the same guarantees (driver floors, digest pins, capability gating). Available frameworks:
certified:pytorch — latest PyTorch + torchvision (CUDA-matched wheels) with JupyterLab
- certified:cuda-devel — the CUDA compiler toolchain (nvcc, headers, dev libraries) for building extensions the runtime base can't compile
- certified:jupyter — JupyterLab on the lean base
certified:— a specific framework version (the version picker), e.g.@ certified:pytorch@2.13. Versions are CUDA-generation-specific: a version only launches on GPUs whose CUDA variant it was built for. A barecertified:uses the default build for the placed machine's CUDA generation.raw-vm— a VM we bootstrap for you with root access, on the provider's default OS. The CLI spellingraw-vmmaps to the API wire valueraw_vm.raw-vm:— a root VM with a chosen operating system (the OS picker), e.g.raw-vm:ubuntu-24.04. Rungpu environmentsfor the OS catalog.provider-template— launch from the provider's own runtime template (container-native or otherwise non-normalizable capacity). These machines launch without the GPU.ai Certified Image.
gpu environments to list every framework, version, and OS you can pass here. Leaving --environment empty uses the provider default.
A framework that isn't published for the selected machine is rejected synchronously with 422 environment_unavailable — *"the selected framework environment isn't available for this machine — pick another framework or the certified base image"*.
Capability gate (422). The environment you pass is re-validated server-side against the availability catalog. If no offering of the requested GPU type can honor the class, the launch is rejected with a 422 environment_unavailable problem+json — never a silent substitution. For example:
--environment raw-vmon container-only capacity → *"this machine is container-native — root VM access isn't available"*--environment certifiedon template-only capacity → *"this provider launches from its own template; the GPU.ai Certified Image isn't available"*
gpu pricing --certified (or --type vm) to find machines that can honor the environment you want before launching.
Pinning an exact offering
--offering-id pins the launch to one exact offering ID (from the offering_id field of gpu pricing --output json). This is an exact pin: if that specific offering is no longer available at launch time, the launch fails with an explicit error — *"selected machine is no longer available — pick another offering"* — and never silently falls back to a different (possibly pricier) offering. Leave --offering-id empty for normal price-sorted placement.
Choosing a disk size
--disk sets the instance filesystem size in GB (10–1000). Every launch gets 100 GB by default — leaving --disk unset never narrows placement and costs nothing extra. Disk beyond the included 100 GB is billed at the offering's per-GB hourly rate (disk_price_per_gb_hour in gpu pricing JSON), folded into the instance's single hourly price — the rate shown at create time is the rate billed.
Setting it is a hard requirement, not a hint: placement narrows to capacity that can honor the size (the disk_configurable field in gpu pricing — a trailing + in the DISK (GB) column), and a launch that can't get the disk it asked for fails with a 422 disk_unavailable problem+json — *"the selected machine cannot be configured with a custom disk size — pick another machine or launch with the default disk"* — never a silent launch at a different size.
The size itself is honored the same way. On an unpinned launch, placement only selects hosts whose real storage fits the request — a machine that can't fit it is skipped, never silently clamped. On a pinned launch (--offering-id), asking for more disk than the offering's displayed storage_gb (in gpu pricing JSON) is refused up front with a 422 disk_exceeds_offering problem+json — *"requested disk_gb exceeds the storage this machine can deliver — lower disk_gb or pick another machine"* — rather than launching with a clamped filesystem.
Machines whose DISK (GB) column has no + bring their own fixed disk (typically full-VM capacity); the shown figure is what you get.
Placement modes & the price cap
Every launch runs in one of two placement modes, and the CLI states which one on every create:
- Pinned (
--offering-idset) — the exact offering you chose, at its listed rate, or an explicit error. Nothing is ever substituted, so the price you saw ingpu pricingis the price you get. - Unpinned (no
--offering-id) — the cheapest capable capacity matching your filters wins, and the final rate is whatever that placement costs, bounded by the price cap.
--max-price is that cap on the retail $/hr (whole node). It is enforced on every placement attempt — including fallbacks when the cheapest offering ghosts, and any boot-rescue reprovision later — so a launch is never billed above it. The trade-off is real: capacity priced above the cap is skipped, which shrinks the pool placement (and a rescue) can draw from.
If you don't pass --max-price on an unpinned launch, the CLI defaults the cap to the cheapest currently-listed price matching your filters — so by default, the price you see quoted at create time is the most you can be billed. Pass --max-price 0 explicitly to launch uncapped ("just give me the market price"); the final rate is then set at placement and returned as price_per_hour on the created instance.
If the cheapest available capacity exceeds the cap at placement time, the launch fails with the current best price so you can re-run to accept it or raise --max-price — never a silent launch above your cap. Even on an uncapped launch, a boot rescue can never re-bind the instance above the rate that was originally placed.
Examples
# Launch a single H100 SXM on-demand
gpu instances create -t h100_sxm --tier on_demand
# Pin to a region and inject an SSH key
gpu instances create -t a100_pcie --region us-east --ssh-key-id key-abc123
# Don't wait — just submit and print operation_id
gpu instances create -t h100_sxm --wait-timeout 0
# Multi-GPU instance with a custom name
gpu instances create -t h100_sxm --count 4 --name training-rig
# Launch the GPU.ai Certified Image (fails 422 if the machine can't run it)
gpu instances create -t rtx_pro_6000_blackwell --environment certified
# Launch the PyTorch framework environment on the certified base
gpu instances create -t h100_sxm --environment certified:pytorch
# CUDA devel — nvcc + headers for building extensions
gpu instances create -t h100_sxm --environment certified:cuda-devel
# Raw VM with root access
gpu instances create -t h100_sxm --environment raw-vm
# Ask for a 200 GB filesystem (fails 422 disk_unavailable if nothing can honor it)
gpu instances create -t h100_sxm --disk 200
# Pin one exact offering (fails if it's gone — never substitutes)
gpu instances create -t h100_sxm --offering-id off_abc123
# Cap the price: place at or below $2.50/hr, never above (fails with the current price if the cheapest is over)
gpu instances create -t h100_sxm --max-price 2.50
# Uncapped: take the market price, whatever placement costs (rate returned on the instance)
gpu instances create -t h100_sxm --max-price 0
Options
--count int Number of GPUs (default 1)
--disk int Instance filesystem size in GB (10-1000). 0 = the platform default (100 GB), which never narrows placement. Disk beyond the included 100 GB is billed at the offering's disk_price_per_gb_hour (see gpu pricing), folded into the hourly rate. Setting it narrows to capacity that can honor it; an unhonorable request fails rather than launching with a different size
--environment string Launch environment: certified (GPU.ai Certified Image) | certified:<framework> (pytorch, cuda-devel, jupyter — a framework layer on the certified base) | raw-vm (root VM access) | provider-template; empty = provider default
-h, --help help for create
--max-price float Cap the retail $/hr (whole node); placement and any boot rescue never exceed it. On an unpinned launch the cap DEFAULTS to the cheapest currently-listed matching price; pass 0 explicitly to launch uncapped. Fails with the current price if the cheapest available is above the cap
--name string Optional instance name
--offering-id string Pin the launch to one exact offering ID; empty = price-sorted placement
--region string Region (e.g., us-east); empty = any
--ssh-key-id strings SSH key ID to inject (may repeat)
--tier string Tier: on_demand | spot (default "on_demand")
-t, --type string GPU type ID (e.g., h100_sxm) — required
--wait-timeout duration How long to poll for status=running before printing the operation_id (default 5m0s)
Options inherited from parent commands
--api-base string API base URL (override with GPUAI_API_BASE env) (default "https://api.gpu.ai/v1")
--debug Enable debug logging to stderr
-o, --output string Output format: table|json (default table on TTY, json otherwise)
SEE ALSO
- gpu instances - Manage GPU instances