CH·02CLI reference

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 bare certified: 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 spelling raw-vm maps to the API wire value raw_vm.
  • raw-vm: — a root VM with a chosen operating system (the OS picker), e.g. raw-vm:ubuntu-24.04. Run gpu environments for 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.
Run 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-vm on container-only capacity → *"this machine is container-native — root VM access isn't available"*
  • --environment certified on template-only capacity → *"this provider launches from its own template; the GPU.ai Certified Image isn't available"*
Use 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-id set) — the exact offering you chose, at its listed rate, or an explicit error. Nothing is ever substituted, so the price you saw in gpu pricing is 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

← The gpu CLI